summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--OWNERS8
-rw-r--r--android/app/OWNERS14
-rw-r--r--android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp22
-rw-r--r--android/app/jni/com_android_bluetooth_vc.cpp12
-rw-r--r--android/app/res/values/config.xml1
-rw-r--r--android/app/src/com/android/bluetooth/a2dp/A2dpService.java12
-rw-r--r--android/app/src/com/android/bluetooth/btservice/AdapterProperties.java14
-rw-r--r--android/app/src/com/android/bluetooth/btservice/AdapterService.java18
-rw-r--r--android/app/src/com/android/bluetooth/btservice/JniCallbacks.java4
-rw-r--r--android/app/src/com/android/bluetooth/btservice/PhonePolicy.java10
-rw-r--r--android/app/src/com/android/bluetooth/btservice/RemoteDevices.java101
-rw-r--r--android/app/src/com/android/bluetooth/btservice/ServiceFactory.java5
-rw-r--r--android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java12
-rw-r--r--android/app/src/com/android/bluetooth/gatt/AppScanStats.java14
-rw-r--r--android/app/src/com/android/bluetooth/gatt/GattService.java7
-rw-r--r--android/app/src/com/android/bluetooth/gatt/HandleMap.java21
-rw-r--r--android/app/src/com/android/bluetooth/gatt/ScanManager.java12
-rw-r--r--android/app/src/com/android/bluetooth/hap/HapClientService.java766
-rw-r--r--android/app/src/com/android/bluetooth/hap/HapClientStackEvent.java43
-rw-r--r--android/app/src/com/android/bluetooth/hap/HapClientStateMachine.java8
-rw-r--r--android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java15
-rw-r--r--android/app/src/com/android/bluetooth/hfp/HeadsetService.java13
-rw-r--r--android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java26
-rw-r--r--android/app/src/com/android/bluetooth/le_audio/LeAudioService.java59
-rw-r--r--android/app/src/com/android/bluetooth/mcp/McpService.java25
-rw-r--r--android/app/src/com/android/bluetooth/sap/SapServer.java5
-rw-r--r--android/app/src/com/android/bluetooth/tbs/TbsGeneric.java68
-rw-r--r--android/app/src/com/android/bluetooth/vc/VolumeControlNativeInterface.java8
-rw-r--r--android/app/src/com/android/bluetooth/vc/VolumeControlService.java80
-rw-r--r--android/app/src/com/android/bluetooth/vc/VolumeControlStackEvent.java12
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpStateMachineTest.java1
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java114
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hap/HapClientTest.java513
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/mcp/McpServiceTest.java31
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/tbs/TbsGenericTest.java4
-rw-r--r--android/blueberry/OWNERS5
-rw-r--r--android/blueberry/server/Android.bp25
-rw-r--r--android/blueberry/server/AndroidManifest.xml29
-rw-r--r--android/blueberry/server/README.md117
-rwxr-xr-xandroid/blueberry/server/scripts/setup.sh12
-rw-r--r--android/blueberry/server/src/com/android/blueberry/Server.kt50
-rwxr-xr-xbuild.py43
-rw-r--r--floss/OWNERS1
-rw-r--r--floss/build/Dockerfile76
-rw-r--r--floss/build/README.md23
-rwxr-xr-xfloss/build/build-in-docker.py163
-rwxr-xr-xfloss/build/docker-build-image.py147
-rwxr-xr-xfloss/build/llvm-rename.sh57
-rw-r--r--framework/Android.bp6
-rw-r--r--framework/OWNERS (renamed from framework/java/android/bluetooth/OWNERS)2
-rw-r--r--framework/api/current.txt4
-rw-r--r--framework/api/system-current.txt27
-rw-r--r--framework/java/android/bluetooth/BluetoothAdapter.java39
-rwxr-xr-xframework/java/android/bluetooth/BluetoothClass.java2
-rw-r--r--framework/java/android/bluetooth/BluetoothDevice.java33
-rw-r--r--framework/java/android/bluetooth/BluetoothHapClient.java677
-rw-r--r--framework/java/android/bluetooth/BluetoothHapPresetInfo.java6
-rw-r--r--framework/java/android/bluetooth/BluetoothHeadset.java17
-rw-r--r--framework/java/android/bluetooth/BluetoothHeadsetClient.java215
-rw-r--r--framework/java/android/bluetooth/BluetoothLeAudioCodecConfig.java4
-rw-r--r--framework/java/android/bluetooth/BluetoothProfile.java5
-rw-r--r--framework/java/android/bluetooth/BluetoothStatusCodes.java2
-rw-r--r--framework/java/android/bluetooth/BluetoothUuid.java8
-rw-r--r--framework/tests/Android.bp16
-rw-r--r--service/Android.bp14
-rw-r--r--service/OWNERS6
-rw-r--r--service/java/com/android/server/bluetooth/BluetoothAirplaneModeListener.java4
-rw-r--r--service/java/com/android/server/bluetooth/BluetoothDeviceConfigListener.java4
-rw-r--r--service/java/com/android/server/bluetooth/BluetoothManagerService.java133
-rw-r--r--service/java/com/android/server/bluetooth/BluetoothModeChangeHelper.java2
-rw-r--r--service/java/com/android/server/bluetooth/BluetoothService.java5
-rw-r--r--service/tests/Android.bp51
-rw-r--r--service/tests/AndroidManifest.xml42
-rw-r--r--service/tests/AndroidTest.xml36
-rw-r--r--service/tests/src/com/android/server/BluetoothAirplaneModeListenerTest.java2
-rw-r--r--system/Android.bp16
-rw-r--r--system/OWNERS13
-rw-r--r--system/audio_bluetooth_hw/Android.bp14
-rw-r--r--system/audio_bluetooth_hw/device_port_proxy.cc388
-rw-r--r--system/audio_bluetooth_hw/device_port_proxy.h200
-rw-r--r--system/audio_bluetooth_hw/device_port_proxy_hidl.cc608
-rw-r--r--system/audio_bluetooth_hw/device_port_proxy_hidl.h116
-rw-r--r--system/audio_bluetooth_hw/stream_apis.cc373
-rw-r--r--system/audio_bluetooth_hw/stream_apis.h10
-rw-r--r--system/audio_hal_interface/Android.bp2
-rw-r--r--system/audio_hal_interface/a2dp_encoding.cc8
-rw-r--r--system/audio_hal_interface/a2dp_encoding.h2
-rw-r--r--system/audio_hal_interface/a2dp_encoding_host.cc3
-rw-r--r--system/audio_hal_interface/aidl/a2dp_encoding.cc12
-rw-r--r--system/audio_hal_interface/aidl/a2dp_encoding.h4
-rw-r--r--system/audio_hal_interface/aidl/audio_aidl_interfaces.h6
-rw-r--r--system/audio_hal_interface/aidl/bluetooth_audio_port_impl.cc8
-rw-r--r--system/audio_hal_interface/aidl/bluetooth_audio_port_impl.h4
-rw-r--r--system/audio_hal_interface/aidl/client_interface.cc25
-rw-r--r--system/audio_hal_interface/aidl/client_interface.h4
-rw-r--r--system/audio_hal_interface/aidl/codec_status.cc20
-rw-r--r--system/audio_hal_interface/aidl/le_audio_software.cc17
-rw-r--r--system/audio_hal_interface/aidl/transport_instance.h4
-rw-r--r--system/audio_hal_interface/fuzzer/Android.bp3
-rw-r--r--system/audio_hal_interface/fuzzer/libbt_audio_hal_client_interface_fuzzer.cpp4
-rw-r--r--system/audio_hal_interface/hal_version_manager.cc31
-rw-r--r--system/audio_hal_interface/hal_version_manager.h16
-rw-r--r--system/audio_hal_interface/hal_version_manager_host.cc5
-rw-r--r--system/audio_hal_interface/hidl/a2dp_encoding_hidl.cc11
-rw-r--r--system/audio_hal_interface/hidl/a2dp_encoding_hidl.h3
-rw-r--r--system/audio_hal_interface/hidl/client_interface_hidl.cc299
-rw-r--r--system/audio_hal_interface/hidl/client_interface_hidl.h58
-rw-r--r--system/audio_hal_interface/hidl/client_interface_hidl_unittest.cc4
-rw-r--r--system/audio_hal_interface/hidl/codec_status_hidl.h2
-rw-r--r--system/audio_hal_interface/hidl/hearing_aid_software_encoding_hidl.cc2
-rw-r--r--system/audio_hal_interface/hidl/le_audio_software_hidl.cc220
-rw-r--r--system/audio_hal_interface/hidl/le_audio_software_hidl.h15
-rw-r--r--system/audio_hal_interface/le_audio_software.cc72
-rw-r--r--system/binder/Android.bp1
-rw-r--r--system/binder/android/bluetooth/IBluetoothHapClient.aidl44
-rw-r--r--system/binder/android/bluetooth/IBluetoothHapClientCallback.aidl39
-rw-r--r--system/binder/android/bluetooth/IBluetoothHearingAid.aidl2
-rw-r--r--system/blueberry/facade/topshim/facade.proto3
-rw-r--r--system/blueberry/tests/gd/cert/gd_device.py90
-rw-r--r--system/blueberry/tests/gd/rust/topshim/facade/automation_helper.py5
-rw-r--r--system/blueberry/tests/gd/rust/topshim/facade/suspend_test.py42
-rw-r--r--system/blueberry/tests/gd_sl4a/gd_sl4a_device_config.yaml35
-rw-r--r--system/blueberry/tests/gd_sl4a/gd_sl4a_test_runner.py62
-rw-r--r--system/blueberry/tests/gd_sl4a/hci/le_advanced_scanning_test.py249
-rw-r--r--system/blueberry/tests/gd_sl4a/lib/ble_lib.py259
-rw-r--r--system/blueberry/tests/gd_sl4a/lib/bt_constants.py740
-rw-r--r--system/blueberry/tests/gd_sl4a/lib/gd_sl4a_base_test.py158
-rw-r--r--system/bta/Android.bp124
-rw-r--r--system/bta/ag/bta_ag_act.cc1
-rw-r--r--system/bta/csis/csis_client_test.cc12
-rw-r--r--system/bta/dm/bta_dm_act.cc40
-rw-r--r--system/bta/dm/bta_dm_api.cc14
-rw-r--r--system/bta/dm/bta_dm_int.h11
-rw-r--r--system/bta/gatt/database.cc1
-rw-r--r--system/bta/groups/groups_test.cc6
-rw-r--r--system/bta/has/has_client.cc12
-rw-r--r--system/bta/has/has_client_test.cc6
-rw-r--r--system/bta/has/has_types.h2
-rw-r--r--system/bta/hearing_aid/hearing_aid.cc38
-rw-r--r--system/bta/include/bta_api.h11
-rw-r--r--system/bta/include/bta_hearing_aid_api.h5
-rw-r--r--system/bta/include/bta_le_audio_api.h14
-rw-r--r--system/bta/le_audio/audio_set_configurations.fbs73
-rw-r--r--system/bta/le_audio/audio_set_configurations.json2118
-rw-r--r--system/bta/le_audio/audio_set_scenarios.fbs36
-rw-r--r--system/bta/le_audio/audio_set_scenarios.json63
-rw-r--r--system/bta/le_audio/broadcaster/broadcaster.cc4
-rw-r--r--system/bta/le_audio/broadcaster/mock_ble_advertising_manager.h5
-rw-r--r--system/bta/le_audio/broadcaster/state_machine_test.cc8
-rw-r--r--system/bta/le_audio/client.cc196
-rw-r--r--system/bta/le_audio/client_linux.cc10
-rw-r--r--system/bta/le_audio/codec_manager.cc191
-rw-r--r--system/bta/le_audio/codec_manager.h14
-rw-r--r--system/bta/le_audio/devices.cc9
-rw-r--r--system/bta/le_audio/devices_test.cc20
-rw-r--r--system/bta/le_audio/hal_verifier.cc9
-rw-r--r--system/bta/le_audio/hal_verifier_linux.cc1
-rw-r--r--system/bta/le_audio/le_audio_client_test.cc57
-rw-r--r--system/bta/le_audio/le_audio_set_configuration_provider.cc28
-rw-r--r--system/bta/le_audio/le_audio_set_configuration_provider.h40
-rw-r--r--system/bta/le_audio/le_audio_set_configuration_provider_json.cc452
-rw-r--r--system/bta/le_audio/le_audio_types.cc13
-rw-r--r--system/bta/le_audio/le_audio_types.h320
-rw-r--r--system/bta/le_audio/mock_codec_manager.cc21
-rw-r--r--system/bta/le_audio/mock_codec_manager.h9
-rw-r--r--system/bta/le_audio/mock_iso_manager.h6
-rw-r--r--system/bta/le_audio/state_machine.cc23
-rw-r--r--system/bta/le_audio/state_machine_test.cc42
-rw-r--r--system/bta/vc/devices.h1
-rw-r--r--system/bta/vc/types.h4
-rw-r--r--system/bta/vc/vc.cc37
-rw-r--r--system/bta/vc/vc_test.cc21
-rw-r--r--system/btcore/fuzzer/btcore_property_fuzzer.cpp4
-rw-r--r--system/btcore/include/property.h6
-rw-r--r--system/btcore/src/property.cc12
-rw-r--r--system/btcore/test/property_test.cc6
-rw-r--r--system/btif/Android.bp4
-rw-r--r--system/btif/include/btif_common.h3
-rw-r--r--system/btif/include/btif_dm.h2
-rw-r--r--system/btif/src/bluetooth.cc25
-rw-r--r--system/btif/src/btif_av.cc9
-rw-r--r--system/btif/src/btif_core.cc4
-rw-r--r--system/btif/src/btif_debug_btsnoop.cc201
-rw-r--r--system/btif/src/btif_dm.cc12
-rw-r--r--system/btif/src/btif_hh.cc14
-rw-r--r--system/btif/src/btif_le_audio.cc13
-rw-r--r--system/btif/src/btif_le_audio_broadcaster.cc4
-rw-r--r--system/btif/src/btif_sock_thread.cc4
-rw-r--r--system/btif/src/btif_storage.cc10
-rw-r--r--system/btif/src/btif_util.cc2
-rw-r--r--system/btif/src/btif_vc.cc16
-rw-r--r--system/btif/src/stack_manager.cc3
-rw-r--r--system/btif/test/btif_core_test.cc2
-rw-r--r--system/build/Android.bp2
-rw-r--r--system/build/dpkg/libchrome-822064/debian/README.Debian1
-rw-r--r--system/build/dpkg/libchrome-822064/debian/changelog5
-rw-r--r--system/build/dpkg/libchrome-822064/debian/compat1
-rw-r--r--system/build/dpkg/libchrome-822064/debian/control28
-rwxr-xr-xsystem/build/dpkg/libchrome-822064/debian/install_headers.sh50
-rw-r--r--system/build/dpkg/libchrome-822064/debian/libchrome.install4
-rw-r--r--system/build/dpkg/libchrome-822064/debian/patches/0001-Add-missing-includes.patch37
-rw-r--r--system/build/dpkg/libchrome-822064/debian/patches/0001-rebase_path-for-write_args.patch34
-rw-r--r--system/build/dpkg/libchrome-822064/debian/patches/series3
-rwxr-xr-xsystem/build/dpkg/libchrome-822064/debian/rules38
-rwxr-xr-xsystem/build/dpkg/libchrome-822064/gen-src-pkg.sh60
-rw-r--r--system/build/dpkg/libchrome/debian/changelog6
-rw-r--r--system/build/dpkg/libchrome/debian/control3
-rwxr-xr-xsystem/build/dpkg/libchrome/debian/install_headers.sh11
-rw-r--r--system/build/dpkg/libchrome/debian/libchrome.install.docker5
-rw-r--r--system/build/dpkg/libchrome/debian/patches/0001-Fix-build-issues-on-930012.patch37
-rw-r--r--system/build/dpkg/libchrome/debian/patches/0001-Remove-absl-from-pkgconfig.patch (renamed from system/build/dpkg/libchrome-822064/debian/patches/0001-Remove-absl-from-pkgconfig.patch)0
-rw-r--r--system/build/dpkg/libchrome/debian/patches/0001-common-mk-rebase_path-output-location-of-generate-pc.patch36
-rw-r--r--system/build/dpkg/libchrome/debian/patches/series3
-rwxr-xr-xsystem/build/dpkg/libchrome/debian/rules8
-rwxr-xr-xsystem/build/dpkg/libchrome/gen-src-pkg.sh27
-rw-r--r--system/build/dpkg/modp_b64/debian/modp-b64.install.docker3
-rwxr-xr-xsystem/build/dpkg/modp_b64/gen-src-pkg.sh9
-rw-r--r--system/common/message_loop_thread.h5
-rw-r--r--system/common/once_timer.h5
-rw-r--r--system/common/repeating_timer.h5
-rw-r--r--system/device/include/controller.h1
-rw-r--r--system/embdrv/lc3/fuzzer/liblc3encoder_fuzzer.cpp3
-rw-r--r--system/embdrv/lc3/include/lc3.h26
-rw-r--r--system/embdrv/lc3/include/lc3_private.h4
-rw-r--r--system/embdrv/lc3/src/bits.h2
-rw-r--r--system/embdrv/lc3/src/lc3.c65
-rw-r--r--system/embdrv/lc3/src/mdct.c10
-rw-r--r--system/embdrv/lc3/src/mdct.h6
-rw-r--r--system/embdrv/lc3/src/tns.c2
-rw-r--r--system/embdrv/lc3_dec/Android.bp69
-rw-r--r--system/embdrv/lc3_dec/Api/Lc3Config.hpp208
-rw-r--r--system/embdrv/lc3_dec/Api/Lc3Decoder.hpp346
-rw-r--r--system/embdrv/lc3_dec/Common/DctIV.cpp299
-rw-r--r--system/embdrv/lc3_dec/Common/DctIV.hpp38
-rw-r--r--system/embdrv/lc3_dec/Common/Lc3Config.cpp161
-rw-r--r--system/embdrv/lc3_dec/Common/Tables/BandIndexTables.cpp88
-rw-r--r--system/embdrv/lc3_dec/Common/Tables/BandIndexTables.hpp44
-rw-r--r--system/embdrv/lc3_dec/Common/Tables/LongTermPostfilterCoefficients.cpp241
-rw-r--r--system/embdrv/lc3_dec/Common/Tables/LongTermPostfilterCoefficients.hpp40
-rw-r--r--system/embdrv/lc3_dec/Common/Tables/MdctWindows.cpp1573
-rw-r--r--system/embdrv/lc3_dec/Common/Tables/MdctWindows.hpp44
-rw-r--r--system/embdrv/lc3_dec/Common/Tables/SnsQuantizationTables.cpp363
-rw-r--r--system/embdrv/lc3_dec/Common/Tables/SnsQuantizationTables.hpp40
-rw-r--r--system/embdrv/lc3_dec/Common/Tables/SpectralDataTables.cpp706
-rw-r--r--system/embdrv/lc3_dec/Common/Tables/SpectralDataTables.hpp31
-rw-r--r--system/embdrv/lc3_dec/Common/Tables/TemporalNoiseShapingTables.cpp74
-rw-r--r--system/embdrv/lc3_dec/Common/Tables/TemporalNoiseShapingTables.hpp35
-rw-r--r--system/embdrv/lc3_dec/Common/fft/fft.c677
-rw-r--r--system/embdrv/lc3_dec/Common/fft/fft.h52
-rw-r--r--system/embdrv/lc3_dec/Decoder/ArithmeticDec.cpp251
-rw-r--r--system/embdrv/lc3_dec/Decoder/ArithmeticDec.hpp68
-rw-r--r--system/embdrv/lc3_dec/Decoder/BitReader.cpp50
-rw-r--r--system/embdrv/lc3_dec/Decoder/BitReader.hpp33
-rw-r--r--system/embdrv/lc3_dec/Decoder/DecoderFrame.cpp420
-rw-r--r--system/embdrv/lc3_dec/Decoder/DecoderFrame.hpp147
-rw-r--r--system/embdrv/lc3_dec/Decoder/DecoderTop.cpp54
-rw-r--r--system/embdrv/lc3_dec/Decoder/DecoderTop.hpp85
-rw-r--r--system/embdrv/lc3_dec/Decoder/Lc3Decoder.cpp159
-rw-r--r--system/embdrv/lc3_dec/Decoder/LongTermPostfilter.cpp472
-rw-r--r--system/embdrv/lc3_dec/Decoder/LongTermPostfilter.hpp74
-rw-r--r--system/embdrv/lc3_dec/Decoder/MPVQ.cpp157
-rw-r--r--system/embdrv/lc3_dec/Decoder/MPVQ.hpp36
-rw-r--r--system/embdrv/lc3_dec/Decoder/MdctDec.cpp170
-rw-r--r--system/embdrv/lc3_dec/Decoder/MdctDec.hpp54
-rw-r--r--system/embdrv/lc3_dec/Decoder/PacketLossConcealment.cpp83
-rw-r--r--system/embdrv/lc3_dec/Decoder/PacketLossConcealment.hpp49
-rw-r--r--system/embdrv/lc3_dec/Decoder/ResidualSpectrum.cpp193
-rw-r--r--system/embdrv/lc3_dec/Decoder/ResidualSpectrum.hpp53
-rw-r--r--system/embdrv/lc3_dec/Decoder/SideInformation.cpp199
-rw-r--r--system/embdrv/lc3_dec/Decoder/SideInformation.hpp64
-rw-r--r--system/embdrv/lc3_dec/Decoder/SpectralNoiseShaping.cpp216
-rw-r--r--system/embdrv/lc3_dec/Decoder/SpectralNoiseShaping.hpp50
-rw-r--r--system/embdrv/lc3_dec/Readme.txt145
-rw-r--r--system/embdrv/lc3_dec/TestSupport/Datapoints.hpp48
-rw-r--r--system/embdrv/lc3_dec/TestSupport/DatapointsAndroid.cpp76
-rw-r--r--system/embdrv/lc3_dec/fuzzer/liblc3codec_decoder_fuzzer.cpp49
-rw-r--r--system/embdrv/lc3_dec/fuzzer/liblc3codec_encoder_fuzzer.cpp52
-rw-r--r--system/gd/Android.bp2
-rw-r--r--system/gd/att/att_module.h4
-rw-r--r--system/gd/btaa/activity_attribution.h5
-rwxr-xr-xsystem/gd/cert/run61
-rwxr-xr-xsystem/gd/cert/run_topshim5
-rw-r--r--system/gd/common/callback_list.h6
-rw-r--r--system/gd/common/contextual_callback.h4
-rw-r--r--system/gd/hal/snoop_logger.cc57
-rw-r--r--system/gd/hal/snoop_logger.h11
-rw-r--r--system/gd/hal/snoop_logger_test.cc81
-rw-r--r--system/gd/hci/acl_manager.h5
-rw-r--r--system/gd/hci/acl_manager/acl_connection.h4
-rw-r--r--system/gd/hci/acl_manager/classic_acl_connection.cc2
-rw-r--r--system/gd/hci/acl_manager/classic_acl_connection.h4
-rw-r--r--system/gd/hci/acl_manager/le_acl_connection.cc2
-rw-r--r--system/gd/hci/acl_manager/le_acl_connection.h4
-rw-r--r--system/gd/hci/acl_manager/le_impl.h14
-rw-r--r--system/gd/hci/command_interface.h4
-rw-r--r--system/gd/hci/controller.h4
-rw-r--r--system/gd/hci/hci_layer.h4
-rw-r--r--system/gd/hci/le_advertising_manager.h3
-rw-r--r--system/gd/hci/le_scanning_manager.h3
-rw-r--r--system/gd/hci/vendor_specific_event_manager.h3
-rw-r--r--system/gd/iso/iso_manager.h4
-rw-r--r--system/gd/iso/iso_module.h4
-rw-r--r--system/gd/l2cap/classic/dynamic_channel_manager.h4
-rw-r--r--system/gd/l2cap/classic/dynamic_channel_service.h3
-rw-r--r--system/gd/l2cap/classic/fixed_channel_manager.h4
-rw-r--r--system/gd/l2cap/classic/fixed_channel_service.h3
-rw-r--r--system/gd/l2cap/classic/internal/fixed_channel_impl.h5
-rw-r--r--system/gd/l2cap/classic/internal/link.h4
-rw-r--r--system/gd/l2cap/classic/internal/link_manager.h5
-rw-r--r--system/gd/l2cap/classic/l2cap_classic_module.h5
-rw-r--r--system/gd/l2cap/internal/dynamic_channel_impl.h5
-rw-r--r--system/gd/l2cap/le/dynamic_channel_manager.h4
-rw-r--r--system/gd/l2cap/le/dynamic_channel_service.h3
-rw-r--r--system/gd/l2cap/le/fixed_channel_manager.h4
-rw-r--r--system/gd/l2cap/le/fixed_channel_service.h3
-rw-r--r--system/gd/l2cap/le/internal/fixed_channel_impl.h5
-rw-r--r--system/gd/l2cap/le/internal/link.h4
-rw-r--r--system/gd/l2cap/le/internal/link_manager.h5
-rw-r--r--system/gd/l2cap/le/l2cap_le_module.h5
-rw-r--r--system/gd/neighbor/connectability.h5
-rw-r--r--system/gd/neighbor/discoverability.h5
-rw-r--r--system/gd/neighbor/inquiry.h5
-rw-r--r--system/gd/neighbor/name.h5
-rw-r--r--system/gd/neighbor/name_db.h5
-rw-r--r--system/gd/neighbor/page.h5
-rw-r--r--system/gd/neighbor/scan.h5
-rw-r--r--system/gd/os/Android.bp16
-rw-r--r--system/gd/os/BUILD.gn2
-rw-r--r--system/gd/os/alarm.h5
-rw-r--r--system/gd/os/files.h5
-rw-r--r--system/gd/os/handler.cc (renamed from system/gd/os/linux_generic/handler.cc)32
-rw-r--r--system/gd/os/handler.h7
-rw-r--r--system/gd/os/handler_unittest.cc (renamed from system/gd/os/linux_generic/handler_unittest.cc)2
-rw-r--r--system/gd/os/linux_generic/files.cc14
-rw-r--r--system/gd/os/linux_generic/reactive_semaphore.h6
-rw-r--r--system/gd/os/linux_generic/reactor.cc45
-rw-r--r--system/gd/os/reactor.h23
-rw-r--r--system/gd/os/repeating_alarm.h5
-rw-r--r--system/gd/os/thread.h5
-rw-r--r--system/gd/rust/facade/src/main.rs11
-rw-r--r--system/gd/rust/facade_proto/build.rs30
-rw-r--r--system/gd/rust/linux/client/src/command_handler.rs118
-rw-r--r--system/gd/rust/linux/client/src/dbus_iface.rs16
-rw-r--r--system/gd/rust/linux/service/src/iface_bluetooth.rs20
-rw-r--r--system/gd/rust/linux/stack/src/bluetooth.rs117
-rw-r--r--system/gd/rust/linux/stack/src/lib.rs9
-rw-r--r--system/gd/rust/topshim/facade/Android.bp1
-rw-r--r--system/gd/rust/topshim/facade/src/adapter_service.rs8
-rw-r--r--system/gd/rust/topshim/gatt/gatt_ble_scanner_shim.cc251
-rw-r--r--system/gd/rust/topshim/gatt/gatt_ble_scanner_shim.h106
-rw-r--r--system/gd/rust/topshim/macros/src/lib.rs18
-rw-r--r--system/gd/rust/topshim/src/btif.rs99
-rw-r--r--system/gd/rust/topshim/src/lib.rs20
-rw-r--r--system/gd/rust/topshim/src/profiles/gatt.rs360
-rw-r--r--system/gd/rust/topshim/src/profiles/mod.rs2
-rw-r--r--system/gd/rust/topshim/src/topstack.rs53
-rw-r--r--system/gd/security/facade_configuration_api.h4
-rw-r--r--system/gd/security/security_manager.h4
-rw-r--r--system/gd/security/security_module.h4
-rw-r--r--system/gd/security/test/mocks.h6
-rw-r--r--system/gd/shim/dumpsys.h5
-rw-r--r--system/gd/storage/config_cache.h5
-rw-r--r--system/gd/storage/storage_module.h5
-rw-r--r--system/include/hardware/bluetooth.h12
-rw-r--r--system/include/hardware/bt_has.h7
-rw-r--r--system/include/hardware/bt_vc.h4
-rw-r--r--system/main/Android.bp6
-rw-r--r--system/main/shim/acl.h5
-rw-r--r--system/main/shim/btm.cc4
-rw-r--r--system/main/shim/btm_api.cc7
-rw-r--r--system/main/shim/btm_api.h11
-rw-r--r--system/main/shim/controller.cc9
-rw-r--r--system/main/shim/le_scanning_manager.cc14
-rw-r--r--system/main/shim/stack.h5
-rw-r--r--system/packet/avrcp/avrcp_browse_packet.h7
-rw-r--r--system/packet/avrcp/avrcp_packet.h5
-rw-r--r--system/profile/avrcp/connection_handler.h4
-rw-r--r--system/profile/avrcp/device.h5
-rw-r--r--system/service/a2dp_sink.h13
-rw-r--r--system/service/a2dp_source.h13
-rw-r--r--system/service/adapter.cc5
-rw-r--r--system/service/adapter.h8
-rw-r--r--system/service/avrcp_control.h10
-rw-r--r--system/service/avrcp_target.cc1
-rw-r--r--system/service/avrcp_target.h12
-rw-r--r--system/service/bluetooth_instance.h13
-rw-r--r--system/service/bluetooth_interface.cc2
-rw-r--r--system/service/client/main.cc35
-rw-r--r--system/service/common/bluetooth/advertise_data.h2
-rw-r--r--system/service/common/bluetooth/advertise_settings.h1
-rw-r--r--system/service/common/bluetooth/util/atomic_string.h8
-rw-r--r--system/service/daemon.cc5
-rw-r--r--system/service/daemon.h6
-rw-r--r--system/service/example/heart_rate/heart_rate_server.cc6
-rw-r--r--system/service/example/heart_rate/heart_rate_server.h6
-rw-r--r--system/service/gatt_client.h11
-rw-r--r--system/service/gatt_server.h17
-rw-r--r--system/service/hal/bluetooth_av_interface.cc5
-rw-r--r--system/service/hal/bluetooth_av_interface.h7
-rw-r--r--system/service/hal/bluetooth_avrcp_interface.cc6
-rw-r--r--system/service/hal/bluetooth_avrcp_interface.h7
-rw-r--r--system/service/hal/bluetooth_gatt_interface.cc6
-rw-r--r--system/service/hal/bluetooth_gatt_interface.h6
-rw-r--r--system/service/hal/bluetooth_interface.cc14
-rw-r--r--system/service/hal/bluetooth_interface.h10
-rw-r--r--system/service/hal/fake_bluetooth_av_interface.h7
-rw-r--r--system/service/hal/fake_bluetooth_gatt_interface.h8
-rw-r--r--system/service/hal/fake_bluetooth_interface.cc1
-rw-r--r--system/service/hal/fake_bluetooth_interface.h6
-rw-r--r--system/service/ipc/binder/bluetooth_a2dp_sink_binder_server.h8
-rw-r--r--system/service/ipc/binder/bluetooth_a2dp_source_binder_server.h9
-rw-r--r--system/service/ipc/binder/bluetooth_avrcp_control_binder_server.h9
-rw-r--r--system/service/ipc/binder/bluetooth_avrcp_target_binder_server.h9
-rw-r--r--system/service/ipc/binder/bluetooth_binder_server.h7
-rw-r--r--system/service/ipc/binder/bluetooth_gatt_client_binder_server.h10
-rw-r--r--system/service/ipc/binder/bluetooth_gatt_server_binder_server.h10
-rw-r--r--system/service/ipc/binder/bluetooth_le_advertiser_binder_server.h10
-rw-r--r--system/service/ipc/binder/bluetooth_le_scanner_binder_server.h9
-rw-r--r--system/service/ipc/binder/bluetooth_low_energy_binder_server.h9
-rw-r--r--system/service/ipc/binder/interface_with_instances_base.h8
-rw-r--r--system/service/ipc/binder/ipc_handler_binder.h8
-rw-r--r--system/service/ipc/binder/remote_callback_list.h6
-rw-r--r--system/service/ipc/binder/remote_callback_map.h6
-rw-r--r--system/service/ipc/dbus/ipc_handler_dbus.h6
-rw-r--r--system/service/ipc/ipc_handler.h7
-rw-r--r--system/service/ipc/ipc_handler_linux.h7
-rw-r--r--system/service/ipc/ipc_manager.h12
-rw-r--r--system/service/logging_helpers.cc2
-rw-r--r--system/service/low_energy_advertiser.h12
-rw-r--r--system/service/low_energy_client.h17
-rw-r--r--system/service/low_energy_scanner.h17
-rw-r--r--system/service/settings.h6
-rw-r--r--system/service/test/a2dp_sink_unittest.cc18
-rw-r--r--system/service/test/a2dp_source_unittest.cc19
-rw-r--r--system/service/test/adapter_unittest.cc12
-rw-r--r--system/service/test/gatt_client_unittest.cc13
-rw-r--r--system/service/test/gatt_server_unittest.cc19
-rw-r--r--system/service/test/ipc_linux_unittest.cc17
-rw-r--r--system/service/test/low_energy_advertiser_unittest.cc20
-rw-r--r--system/service/test/low_energy_client_unittest.cc26
-rw-r--r--system/service/test/low_energy_scanner_unittest.cc20
-rw-r--r--system/service/test/mock_adapter.h6
-rw-r--r--system/service/test/mock_daemon.h6
-rw-r--r--system/service/test/settings_unittest.cc6
-rw-r--r--system/stack/Android.bp2
-rw-r--r--system/stack/acl/btm_ble_connection_establishment.cc44
-rw-r--r--system/stack/avrc/avrc_pars_ct.cc8
-rw-r--r--system/stack/btm/btm_ble.cc26
-rw-r--r--system/stack/btm/btm_ble_addr.cc4
-rw-r--r--system/stack/btm/btm_ble_bgconn.cc6
-rw-r--r--system/stack/btm/btm_ble_int.h1
-rw-r--r--system/stack/btm/btm_inq.cc9
-rw-r--r--system/stack/btm/btm_iso_impl.h56
-rw-r--r--system/stack/btu/btu_hcif.cc15
-rw-r--r--system/stack/eatt/eatt.h5
-rw-r--r--system/stack/hcic/hcicmds.cc167
-rw-r--r--system/stack/include/bt_dev_class.h93
-rw-r--r--system/stack/include/btm_api_types.h93
-rw-r--r--system/stack/include/hcimsgs.h158
-rw-r--r--system/stack/include/inq_hci_link_interface.h6
-rw-r--r--system/stack/l2cap/l2c_api.cc2
-rwxr-xr-x[-rw-r--r--]system/stack/l2cap/l2c_ble.cc40
-rwxr-xr-x[-rw-r--r--]system/stack/l2cap/l2c_csm.cc51
-rw-r--r--system/stack/l2cap/l2c_fcr.cc6
-rw-r--r--system/stack/l2cap/l2c_main.cc8
-rwxr-xr-x[-rw-r--r--]system/stack/l2cap/l2c_utils.cc11
-rw-r--r--system/stack/test/ble_advertiser_test.cc6
-rw-r--r--system/stack/test/btm_iso_test.cc37
-rw-r--r--system/stack/test/common/mock_eatt.h6
-rw-r--r--system/stack/test/fuzzers/Android.bp2
-rw-r--r--system/test/Android.bp7
-rw-r--r--system/test/common/stack_config.cc51
-rw-r--r--system/test/headless/Android.bp2
-rw-r--r--system/test/headless/headless.cc3
-rw-r--r--system/test/mock/mock_bluetooth_interface.cc5
-rw-r--r--system/test/mock/mock_bta_dm_act.h9
-rw-r--r--system/test/mock/mock_bta_leaudio.cc17
-rw-r--r--system/test/mock/mock_device_controller.cc5
-rw-r--r--system/test/mock/mock_le_audio_hal_verifier.cc5
-rw-r--r--system/test/mock/mock_main_shim_btm_api.cc5
-rw-r--r--system/test/mock/mock_main_shim_metrics_api.cc4
-rw-r--r--system/test/mock/mock_stack_acl_btm_ble_connection_establishment.cc15
-rw-r--r--system/test/mock/mock_stack_acl_btm_ble_connection_establishment.h32
-rw-r--r--system/test/mock/mock_stack_btm_ble.cc3
-rw-r--r--system/test/mock/mock_stack_btm_inq.cc6
-rw-r--r--system/test/rootcanal/Android.bp2
-rw-r--r--system/test/stub/osi.cc11
-rw-r--r--system/test/suite/adapter/bluetooth_test.h5
-rw-r--r--system/test/suite/gatt/gatt_test.h5
-rw-r--r--system/tools/bdtool/adapter.c2
-rw-r--r--system/vendor_libs/test_vendor_lib/Android.bp3
-rw-r--r--system/vendor_libs/test_vendor_lib/include/inquiry.h33
-rw-r--r--system/vendor_libs/test_vendor_lib/include/le_advertisement.h40
-rw-r--r--system/vendor_libs/test_vendor_lib/include/sco.h33
-rw-r--r--system/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.cc17
-rw-r--r--system/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.h3
-rw-r--r--system/vendor_libs/test_vendor_lib/model/controller/le_advertiser.cc146
-rw-r--r--system/vendor_libs/test_vendor_lib/model/controller/le_advertiser.h32
-rw-r--r--system/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.cc91
-rw-r--r--system/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.h19
-rw-r--r--system/vendor_libs/test_vendor_lib/model/devices/loopback.cc1
-rw-r--r--system/vendor_libs/test_vendor_lib/model/devices/server_port_factory.cc147
-rw-r--r--system/vendor_libs/test_vendor_lib/model/devices/server_port_factory.h51
-rw-r--r--system/vendor_libs/test_vendor_lib/model/devices/sniffer.cc26
-rw-r--r--system/vendor_libs/test_vendor_lib/net/posix/posix_async_socket.cc2
-rw-r--r--system/vendor_libs/test_vendor_lib/packets/link_layer_packets.pdl16
-rw-r--r--system/vendor_libs/test_vendor_lib/test/iterator_test.cc232
-rw-r--r--system/vendor_libs/test_vendor_lib/test/l2cap_sdu_test.cc122
-rw-r--r--system/vendor_libs/test_vendor_lib/test/l2cap_test.cc517
-rw-r--r--system/vendor_libs/test_vendor_lib/test/link_layer_socket_device_test.cc296
-rw-r--r--system/vendor_libs/test_vendor_lib/test/packet_stream_unittest.cc116
-rw-r--r--system/vendor_libs/test_vendor_lib/types/Android.bp45
-rw-r--r--system/vendor_libs/test_vendor_lib/types/BUILD.gn65
-rw-r--r--system/vendor_libs/test_vendor_lib/types/bluetooth/uuid.cc182
-rw-r--r--system/vendor_libs/test_vendor_lib/types/bluetooth/uuid.h140
-rw-r--r--system/vendor_libs/test_vendor_lib/types/test/bluetooth/uuid_unittest.cc155
516 files changed, 12591 insertions, 15772 deletions
diff --git a/OWNERS b/OWNERS
index 5281ac8593..2d3b648b03 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,12 +1,4 @@
# Project owners
-cmanton@google.com
-cncn@google.com
-hsz@google.com
-jpawlowski@google.com
-mylesgw@google.com
-optedoblivion@google.com
-qasimj@google.com
-rahulsabnis@google.com
sattiraju@google.com
siyuanh@google.com
zachoverflow@google.com
diff --git a/android/app/OWNERS b/android/app/OWNERS
index cc15db5d23..f758f97703 100644
--- a/android/app/OWNERS
+++ b/android/app/OWNERS
@@ -1 +1,13 @@
-include platform/packages/modules/Bluetooth:/OWNERS
+# Reviewers for /android/app
+
+cmanton@google.com
+cncn@google.com
+hsz@google.com
+jpawlowski@google.com
+mylesgw@google.com
+optedoblivion@google.com
+qasimj@google.com
+rahulsabnis@google.com
+sattiraju@google.com
+siyuanh@google.com
+zachoverflow@google.com \ No newline at end of file
diff --git a/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp b/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp
index db1f299f3f..05d1944d48 100644
--- a/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp
+++ b/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp
@@ -599,31 +599,15 @@ static void link_quality_report_callback(
(jint)negative_acknowledgement_count);
}
-static void switch_buffer_size_callback(RawAddress* bd_addr,
- bool is_low_latency_buffer_size) {
-
- if (!bd_addr) {
- ALOGE("Address is null in %s", __func__);
- return;
- }
+static void switch_buffer_size_callback(bool is_low_latency_buffer_size) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
- ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
- if (!addr.get()) {
- ALOGE("Error while allocating in: %s", __func__);
- return;
- }
-
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
- (jbyte*)bd_addr);
-
ALOGV("%s: SwitchBufferSizeCallback: %s", __func__,
is_low_latency_buffer_size ? "true" : "false");
sCallbackEnv->CallVoidMethod(
- sJniCallbacksObj, method_switchBufferSizeCallback, addr.get(),
+ sJniCallbacksObj, method_switchBufferSizeCallback,
(jboolean)is_low_latency_buffer_size);
}
@@ -924,7 +908,7 @@ static void classInitNative(JNIEnv* env, jclass clazz) {
jniCallbackClass, "linkQualityReportCallback", "(JIIIIII)V");
method_switchBufferSizeCallback =
- env->GetMethodID(jniCallbackClass, "switchBufferSizeCallback", "([BZ)V");
+ env->GetMethodID(jniCallbackClass, "switchBufferSizeCallback", "(Z)V");
method_setWakeAlarm = env->GetMethodID(clazz, "setWakeAlarm", "(JZ)Z");
method_acquireWakeLock =
diff --git a/android/app/jni/com_android_bluetooth_vc.cpp b/android/app/jni/com_android_bluetooth_vc.cpp
index ce760c2206..5bb744db7a 100644
--- a/android/app/jni/com_android_bluetooth_vc.cpp
+++ b/android/app/jni/com_android_bluetooth_vc.cpp
@@ -66,7 +66,7 @@ class VolumeControlCallbacksImpl : public VolumeControlCallbacks {
}
void OnVolumeStateChanged(const RawAddress& bd_addr, uint8_t volume,
- bool mute) override {
+ bool mute, bool isAutonomous) override {
LOG(INFO) << __func__;
std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
@@ -83,11 +83,11 @@ class VolumeControlCallbacksImpl : public VolumeControlCallbacks {
sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)&bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVolumeStateChanged,
- (jint)volume, (jboolean)mute, addr.get());
+ (jint)volume, (jboolean)mute, addr.get(), (jboolean)isAutonomous);
}
void OnGroupVolumeStateChanged(int group_id, uint8_t volume,
- bool mute) override {
+ bool mute, bool isAutonomous) override {
LOG(INFO) << __func__;
std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
@@ -96,7 +96,7 @@ class VolumeControlCallbacksImpl : public VolumeControlCallbacks {
sCallbackEnv->CallVoidMethod(mCallbacksObj,
method_onGroupVolumeStateChanged, (jint)volume,
- (jboolean)mute, group_id);
+ (jboolean)mute, group_id, (jboolean)isAutonomous);
}
};
@@ -107,10 +107,10 @@ static void classInitNative(JNIEnv* env, jclass clazz) {
env->GetMethodID(clazz, "onConnectionStateChanged", "(I[B)V");
method_onVolumeStateChanged =
- env->GetMethodID(clazz, "onVolumeStateChanged", "(IZ[B)V");
+ env->GetMethodID(clazz, "onVolumeStateChanged", "(IZ[BZ)V");
method_onGroupVolumeStateChanged =
- env->GetMethodID(clazz, "onGroupVolumeStateChanged", "(IZI)V");
+ env->GetMethodID(clazz, "onGroupVolumeStateChanged", "(IZIZ)V");
LOG(INFO) << __func__ << ": succeeds";
}
diff --git a/android/app/res/values/config.xml b/android/app/res/values/config.xml
index 005d7bd60f..3a709770c1 100644
--- a/android/app/res/values/config.xml
+++ b/android/app/res/values/config.xml
@@ -33,6 +33,7 @@
<bool name="profile_supported_mapmce">false</bool>
<bool name="profile_supported_hid_device">true</bool>
<bool name="profile_supported_le_audio">true</bool>
+ <bool name="profile_supported_le_audio_broadcast">false</bool>
<bool name="profile_supported_vc">true</bool>
<bool name="profile_supported_mcp_server">true</bool>
<bool name="profile_supported_csip_set_coordinator">true</bool>
diff --git a/android/app/src/com/android/bluetooth/a2dp/A2dpService.java b/android/app/src/com/android/bluetooth/a2dp/A2dpService.java
index 7a3b7df82b..a987758aff 100644
--- a/android/app/src/com/android/bluetooth/a2dp/A2dpService.java
+++ b/android/app/src/com/android/bluetooth/a2dp/A2dpService.java
@@ -88,6 +88,9 @@ public class A2dpService extends ProfileService {
// Protect setActiveDevice() so all invoked is handled squentially
private final Object mActiveSwitchingGuard = new Object();
+ // Timeout for state machine thread join, to prevent potential ANR.
+ private static final int SM_THREAD_JOIN_TIMEOUT_MS = 1000;
+
// Upper limit of all A2DP devices: Bonded or Connected
private static final int MAX_A2DP_STATE_MACHINES = 50;
// Upper limit of all A2DP devices that are Connected or Connecting
@@ -216,8 +219,13 @@ public class A2dpService extends ProfileService {
}
if (mStateMachinesThread != null) {
- mStateMachinesThread.quitSafely();
- mStateMachinesThread = null;
+ try {
+ mStateMachinesThread.quitSafely();
+ mStateMachinesThread.join(SM_THREAD_JOIN_TIMEOUT_MS);
+ mStateMachinesThread = null;
+ } catch (InterruptedException e) {
+ // Do not rethrow as we are shutting down anyway
+ }
}
// Step 2: Reset maximum number of connected audio devices
mMaxConnectedAudioDevices = 1;
diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java b/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java
index 743b85a92e..e05dedc210 100644
--- a/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java
+++ b/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java
@@ -1114,11 +1114,21 @@ class AdapterProperties {
writer.println(" " + "DiscoveryEndMs: " + mDiscoveryEndMs);
writer.println(" " + "Bonded devices:");
+ StringBuilder sb = new StringBuilder();
for (BluetoothDevice device : mBondedDevices) {
- writer.println(
- " " + device.getAddress() + " [" + dumpDeviceType(device.getType()) + "] "
+ String address = device.getAddress();
+ String identityAddress = mService.getIdentityAddress(address);
+ if (identityAddress.equals(address)) {
+ writer.println(" " + address
+ + " [" + dumpDeviceType(device.getType()) + "] "
+ Utils.getName(device));
+ } else {
+ sb.append(" " + address + " => " + identityAddress
+ + " [" + dumpDeviceType(device.getType()) + "] "
+ + Utils.getName(device) + "\n");
+ }
}
+ writer.println(sb.toString());
}
private String dumpDeviceType(int deviceType) {
diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterService.java b/android/app/src/com/android/bluetooth/btservice/AdapterService.java
index dd06cd3855..82d1f8d51f 100644
--- a/android/app/src/com/android/bluetooth/btservice/AdapterService.java
+++ b/android/app/src/com/android/bluetooth/btservice/AdapterService.java
@@ -824,15 +824,21 @@ public class AdapterService extends Service {
}
}
- void switchBufferSizeCallback(byte[] address, boolean isLowLatencyBufferSize) {
- BluetoothDevice device = getDeviceFromByte(address);
+ void switchBufferSizeCallback(boolean isLowLatencyBufferSize) {
+ List<BluetoothDevice> activeDevices = getActiveDevices(BluetoothProfile.A2DP);
+ if (activeDevices.size() != 1) {
+ errorLog(
+ "Cannot switch buffer size. The number of A2DP active devices is "
+ + activeDevices.size());
+ }
+
// Send intent to fastpair
Intent switchBufferSizeIntent = new Intent(BluetoothDevice.ACTION_SWITCH_BUFFER_SIZE);
switchBufferSizeIntent.setClassName(
getString(com.android.bluetooth.R.string.peripheral_link_package),
getString(com.android.bluetooth.R.string.peripheral_link_package)
+ getString(com.android.bluetooth.R.string.peripheral_link_service));
- switchBufferSizeIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
+ switchBufferSizeIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, activeDevices.get(0));
switchBufferSizeIntent.putExtra(
BluetoothDevice.EXTRA_LOW_LATENCY_BUFFER_SIZE, isLowLatencyBufferSize);
sendBroadcast(switchBufferSizeIntent);
@@ -1084,7 +1090,7 @@ public class AdapterService extends Service {
* @return true if any profile is enabled, false otherwise
*/
@RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
- private boolean isAnyProfileEnabled(BluetoothDevice device) {
+ boolean isAnyProfileEnabled(BluetoothDevice device) {
if (mA2dpService != null && mA2dpService.getConnectionPolicy(device)
> BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
@@ -4556,8 +4562,8 @@ public class AdapterService extends Service {
* @return true, if the LE audio broadcast source is supported
*/
public boolean isLeAudioBroadcastSourceSupported() {
- //TODO: check the profile support status as well after we have the implementation
- return mAdapterProperties.isLePeriodicAdvertisingSupported()
+ return getResources().getBoolean(R.bool.profile_supported_le_audio_broadcast)
+ && mAdapterProperties.isLePeriodicAdvertisingSupported()
&& mAdapterProperties.isLeExtendedAdvertisingSupported()
&& mAdapterProperties.isLeIsochronousBroadcasterSupported();
}
diff --git a/android/app/src/com/android/bluetooth/btservice/JniCallbacks.java b/android/app/src/com/android/bluetooth/btservice/JniCallbacks.java
index 5d7b49d109..cc0c6a09d4 100644
--- a/android/app/src/com/android/bluetooth/btservice/JniCallbacks.java
+++ b/android/app/src/com/android/bluetooth/btservice/JniCallbacks.java
@@ -106,8 +106,8 @@ final class JniCallbacks {
packets_not_receive_count, negative_acknowledgement_count);
}
- void switchBufferSizeCallback(byte[] mac_address, boolean is_low_latency_buffer_size) {
- mAdapterService.switchBufferSizeCallback(mac_address, is_low_latency_buffer_size);
+ void switchBufferSizeCallback(boolean is_low_latency_buffer_size) {
+ mAdapterService.switchBufferSizeCallback(is_low_latency_buffer_size);
}
}
diff --git a/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java b/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java
index 50aff4ae61..f1cef7af66 100644
--- a/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java
+++ b/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java
@@ -43,6 +43,7 @@ import com.android.bluetooth.Utils;
import com.android.bluetooth.a2dp.A2dpService;
import com.android.bluetooth.btservice.storage.DatabaseManager;
import com.android.bluetooth.csip.CsipSetCoordinatorService;
+import com.android.bluetooth.hap.HapClientService;
import com.android.bluetooth.hearingaid.HearingAidService;
import com.android.bluetooth.hfp.HeadsetService;
import com.android.bluetooth.hid.HidHostService;
@@ -296,6 +297,7 @@ class PhonePolicy {
mFactory.getCsipSetCoordinatorService();
VolumeControlService volumeControlService =
mFactory.getVolumeControlService();
+ HapClientService hapClientService = mFactory.getHapClientService();
// Set profile priorities only for the profiles discovered on the remote device.
// This avoids needless auto-connect attempts to profiles non-existent on the remote device
@@ -364,6 +366,14 @@ class PhonePolicy {
mAdapterService.getDatabase().setProfileConnectionPolicy(device,
BluetoothProfile.VOLUME_CONTROL, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
}
+
+ if ((hapClientService != null) && Utils.arrayContains(uuids,
+ BluetoothUuid.HAS) && (hapClientService.getConnectionPolicy(device)
+ == BluetoothProfile.CONNECTION_POLICY_UNKNOWN)) {
+ debugLog("setting hearing access profile priority for device " + device);
+ mAdapterService.getDatabase().setProfileConnectionPolicy(device,
+ BluetoothProfile.HAP_CLIENT, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
+ }
}
@RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
diff --git a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java
index 540f971679..2d8915388d 100644
--- a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java
+++ b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java
@@ -24,6 +24,7 @@ import android.bluetooth.BluetoothAssignedNumbers;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothHeadsetClient;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.IBluetoothConnectionCallback;
import android.content.BroadcastReceiver;
@@ -71,6 +72,24 @@ final class RemoteDevices {
private final HashMap<String, String> mDualDevicesMap;
private Queue<String> mDeviceQueue;
+ /**
+ * Bluetooth HFP v1.8 specifies the Battery Charge indicator of AG can take values from
+ * {@code 0} to {@code 5}, but it does not specify how to map the values back to percentages.
+ * The following mapping is used:
+ * - Level 0: 0%
+ * - Level 1: midpoint of 1-25%
+ * - Level 2: midpoint of 26-50%
+ * - Level 3: midpoint of 51-75%
+ * - Level 4: midpoint of 76-99%
+ * - Level 5: 100%
+ */
+ private static final int HFP_BATTERY_CHARGE_INDICATOR_0 = 0;
+ private static final int HFP_BATTERY_CHARGE_INDICATOR_1 = 13;
+ private static final int HFP_BATTERY_CHARGE_INDICATOR_2 = 38;
+ private static final int HFP_BATTERY_CHARGE_INDICATOR_3 = 63;
+ private static final int HFP_BATTERY_CHARGE_INDICATOR_4 = 88;
+ private static final int HFP_BATTERY_CHARGE_INDICATOR_5 = 100;
+
private final Handler mHandler;
private class RemoteDevicesHandler extends Handler {
@@ -110,6 +129,12 @@ final class RemoteDevices {
case BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED:
onHeadsetConnectionStateChanged(intent);
break;
+ case BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED:
+ onHeadsetClientConnectionStateChanged(intent);
+ break;
+ case BluetoothHeadsetClient.ACTION_AG_EVENT:
+ onAgIndicatorValueChanged(intent);
+ break;
default:
Log.w(TAG, "Unhandled intent: " + intent);
break;
@@ -157,6 +182,8 @@ final class RemoteDevices {
filter.addCategory(BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY + "."
+ BluetoothAssignedNumbers.APPLE);
filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
+ filter.addAction(BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED);
+ filter.addAction(BluetoothHeadsetClient.ACTION_AG_EVENT);
sAdapterService.registerReceiver(mReceiver, filter);
}
@@ -565,6 +592,38 @@ final class RemoteDevices {
Utils.getTempAllowlistBroadcastOptions());
}
+ /**
+ * Converts HFP's Battery Charge indicator values of {@code 0 -- 5} to an integer percentage.
+ */
+ @VisibleForTesting
+ static int batteryChargeIndicatorToPercentge(int indicator) {
+ int percent;
+ switch (indicator) {
+ case 5:
+ percent = HFP_BATTERY_CHARGE_INDICATOR_5;
+ break;
+ case 4:
+ percent = HFP_BATTERY_CHARGE_INDICATOR_4;
+ break;
+ case 3:
+ percent = HFP_BATTERY_CHARGE_INDICATOR_3;
+ break;
+ case 2:
+ percent = HFP_BATTERY_CHARGE_INDICATOR_2;
+ break;
+ case 1:
+ percent = HFP_BATTERY_CHARGE_INDICATOR_1;
+ break;
+ case 0:
+ percent = HFP_BATTERY_CHARGE_INDICATOR_0;
+ break;
+ default:
+ percent = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
+ }
+ Log.d(TAG, "Battery charge indicator: " + indicator + "; converted to: " + percent + "%");
+ return percent;
+ }
+
private static boolean areUuidsEqual(ParcelUuid[] uuids1, ParcelUuid[] uuids2) {
final int length1 = uuids1 == null ? 0 : uuids1.length;
final int length2 = uuids2 == null ? 0 : uuids2.length;
@@ -663,6 +722,9 @@ final class RemoteDevices {
}
break;
case AbstractionLayer.BT_PROPERTY_TYPE_OF_DEVICE:
+ if (device.isConsolidated()) {
+ return;
+ }
// The device type from hal layer, defined in bluetooth.h,
// matches the type defined in BluetoothDevice.java
device.mDeviceType = Utils.byteArrayToInt(val);
@@ -737,6 +799,7 @@ final class RemoteDevices {
DeviceProperties deviceProperties = getDeviceProperties(device);
deviceProperties.mIsConsolidated = true;
+ deviceProperties.mDeviceType = BluetoothDevice.DEVICE_TYPE_DUAL;
deviceProperties.mIdentityAddress = Utils.getAddressStringFromByte(secondaryAddress);
mDualDevicesMap.put(deviceProperties.getIdentityAddress(), Utils.getAddressStringFromByte(mainAddress));
}
@@ -784,6 +847,12 @@ final class RemoteDevices {
if (sAdapterService.getConnectionState(device) == 0) {
resetBatteryLevel(device);
}
+ if (!sAdapterService.isAnyProfileEnabled(device)) {
+ DeviceProperties deviceProp = getDeviceProperties(device);
+ if (deviceProp != null) {
+ deviceProp.setBondingInitiatedLocally(false);
+ }
+ }
debugLog(
"aclStateChangeCallback: Adapter State: " + BluetoothAdapter.nameForState(state)
+ " Disconnected: " + device
@@ -1038,6 +1107,38 @@ final class RemoteDevices {
return batteryLevel * 100 / (numberOfLevels - 1);
}
+ /**
+ * Handles headset client connection state change event
+ * @param intent must be {@link BluetoothHeadsetClient#ACTION_CONNECTION_STATE_CHANGED} intent
+ */
+ @VisibleForTesting
+ void onHeadsetClientConnectionStateChanged(Intent intent) {
+ BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+ if (device == null) {
+ Log.e(TAG, "onHeadsetClientConnectionStateChanged() remote device is null");
+ return;
+ }
+ if (intent.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED)
+ == BluetoothProfile.STATE_DISCONNECTED) {
+ // TODO: Rework this when non-HFP sources of battery level indication is added
+ resetBatteryLevel(device);
+ }
+ }
+
+ @VisibleForTesting
+ void onAgIndicatorValueChanged(Intent intent) {
+ BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+ if (device == null) {
+ Log.e(TAG, "onAgIndicatorValueChanged() remote device is null");
+ return;
+ }
+
+ if (intent.hasExtra(BluetoothHeadsetClient.EXTRA_BATTERY_LEVEL)) {
+ int batteryLevel = intent.getIntExtra(BluetoothHeadsetClient.EXTRA_BATTERY_LEVEL, -1);
+ updateBatteryLevel(device, batteryChargeIndicatorToPercentge(batteryLevel));
+ }
+ }
+
private static void errorLog(String msg) {
Log.e(TAG, msg);
}
diff --git a/android/app/src/com/android/bluetooth/btservice/ServiceFactory.java b/android/app/src/com/android/bluetooth/btservice/ServiceFactory.java
index 6842dc0de5..f9256ad2a1 100644
--- a/android/app/src/com/android/bluetooth/btservice/ServiceFactory.java
+++ b/android/app/src/com/android/bluetooth/btservice/ServiceFactory.java
@@ -19,6 +19,7 @@ package com.android.bluetooth.btservice;
import com.android.bluetooth.a2dp.A2dpService;
import com.android.bluetooth.avrcp.AvrcpTargetService;
import com.android.bluetooth.csip.CsipSetCoordinatorService;
+import com.android.bluetooth.hap.HapClientService;
import com.android.bluetooth.hearingaid.HearingAidService;
import com.android.bluetooth.hfp.HeadsetService;
import com.android.bluetooth.hid.HidDeviceService;
@@ -73,4 +74,8 @@ public class ServiceFactory {
public VolumeControlService getVolumeControlService() {
return VolumeControlService.getVolumeControlService();
}
+
+ public HapClientService getHapClientService() {
+ return HapClientService.getHapClientService();
+ }
}
diff --git a/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java b/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java
index dec6db2e4b..b127534ff7 100644
--- a/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java
+++ b/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java
@@ -67,6 +67,9 @@ public class CsipSetCoordinatorService extends ProfileService {
private static final boolean DBG = false;
private static final String TAG = "CsipSetCoordinatorService";
+ // Timeout for state machine thread join, to prevent potential ANR.
+ private static final int SM_THREAD_JOIN_TIMEOUT_MS = 1000;
+
// Upper limit of all CSIP devices: Bonded or Connected
private static final int MAX_CSIS_STATE_MACHINES = 10;
private static CsipSetCoordinatorService sCsipSetCoordinatorService;
@@ -182,8 +185,13 @@ public class CsipSetCoordinatorService extends ProfileService {
}
if (mStateMachinesThread != null) {
- mStateMachinesThread.quitSafely();
- mStateMachinesThread = null;
+ try {
+ mStateMachinesThread.quitSafely();
+ mStateMachinesThread.join(SM_THREAD_JOIN_TIMEOUT_MS);
+ mStateMachinesThread = null;
+ } catch (InterruptedException e) {
+ // Do not rethrow as we are shutting down anyway
+ }
}
mDeviceGroupIdMap.clear();
diff --git a/android/app/src/com/android/bluetooth/gatt/AppScanStats.java b/android/app/src/com/android/bluetooth/gatt/AppScanStats.java
index a6c2bb94e6..cdd11f3c91 100644
--- a/android/app/src/com/android/bluetooth/gatt/AppScanStats.java
+++ b/android/app/src/com/android/bluetooth/gatt/AppScanStats.java
@@ -60,11 +60,13 @@ import java.util.Objects;
ContextMap mContextMap;
// GattService is needed to add scan event protos to be dumped later
- GattService mGattService;
+ final GattService mGattService;
// Battery stats is used to keep track of scans and result stats
BatteryStatsManager mBatteryStatsManager;
+ private final AdapterService mAdapterService;
+
class LastScan {
public long duration;
public long suspendDuration;
@@ -164,6 +166,7 @@ import java.util.Objects;
}
mWorkSource = source;
mWorkSourceUtil = new WorkSourceUtil(source);
+ mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService());
}
synchronized void addResult(int scannerId) {
@@ -272,7 +275,7 @@ import java.util.Objects;
mTotalSuspendTime += suspendDuration;
}
mOngoingScans.remove(scannerId);
- if (mLastScans.size() >= getNumScanDurationsKept()) {
+ if (mLastScans.size() >= mAdapterService.getScanQuotaCount()) {
mLastScans.remove(0);
}
mLastScans.add(scan);
@@ -355,19 +358,20 @@ import java.util.Objects;
}
synchronized boolean isScanningTooFrequently() {
- if (mLastScans.size() < getNumScanDurationsKept()) {
+ if (mLastScans.size() < mAdapterService.getScanQuotaCount()) {
return false;
}
return (SystemClock.elapsedRealtime() - mLastScans.get(0).timestamp)
- < getExcessiveScanningPeriodMillis();
+ < mAdapterService.getScanQuotaWindowMillis();
}
synchronized boolean isScanningTooLong() {
if (!isScanning()) {
return false;
}
- return (SystemClock.elapsedRealtime() - mScanStartTime) > getScanTimeoutMillis();
+ return (SystemClock.elapsedRealtime() - mScanStartTime)
+ > mAdapterService.getScanTimeoutMillis();
}
synchronized boolean hasRecentScan() {
diff --git a/android/app/src/com/android/bluetooth/gatt/GattService.java b/android/app/src/com/android/bluetooth/gatt/GattService.java
index 2c360f574d..a8a4db2ad2 100644
--- a/android/app/src/com/android/bluetooth/gatt/GattService.java
+++ b/android/app/src/com/android/bluetooth/gatt/GattService.java
@@ -167,8 +167,7 @@ public class GattService extends ProfileService {
UUID.fromString("00001850-0000-1000-8000-00805F9B34FB"), // PACS
UUID.fromString("0000184E-0000-1000-8000-00805F9B34FB"), // ASCS
UUID.fromString("0000184F-0000-1000-8000-00805F9B34FB"), // BASS
- /* FIXME: Not known yet, using a placeholder instead. */
- UUID.fromString("EEEEEEEE-EEEE-EEEE-EEEE-EEEEEEEEEEEE"), // HAP
+ UUID.fromString("00001854-0000-1000-8000-00805F9B34FB"), // HAP
};
/**
@@ -315,7 +314,7 @@ public class GattService extends ProfileService {
mAdvertiseManager = new AdvertiseManager(this, mAdapterService);
mAdvertiseManager.start();
- mScanManager = new ScanManager(this);
+ mScanManager = new ScanManager(this, mAdapterService);
mScanManager.start();
mPeriodicScanManager = new PeriodicScanManager(mAdapterService);
@@ -3454,7 +3453,7 @@ public class GattService extends ProfileService {
return new ArrayList<>(0);
}
List<ParcelUuid> serviceUuids = new ArrayList<ParcelUuid>();
- for (HandleMap.Entry entry : mHandleMap.mEntries) {
+ for (HandleMap.Entry entry : mHandleMap.getEntries()) {
serviceUuids.add(new ParcelUuid(entry.uuid));
}
return serviceUuids;
diff --git a/android/app/src/com/android/bluetooth/gatt/HandleMap.java b/android/app/src/com/android/bluetooth/gatt/HandleMap.java
index 2b662d6011..2d8d9369e1 100644
--- a/android/app/src/com/android/bluetooth/gatt/HandleMap.java
+++ b/android/app/src/com/android/bluetooth/gatt/HandleMap.java
@@ -17,12 +17,11 @@ package com.android.bluetooth.gatt;
import android.util.Log;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
class HandleMap {
private static final boolean DBG = GattServiceConfig.DBG;
@@ -88,8 +87,8 @@ class HandleMap {
int mLastCharacteristic = 0;
HandleMap() {
- mEntries = new ArrayList<Entry>();
- mRequestMap = new HashMap<Integer, Integer>();
+ mEntries = new CopyOnWriteArrayList<Entry>();
+ mRequestMap = new ConcurrentHashMap<Integer, Integer>();
}
void clear() {
@@ -144,16 +143,8 @@ class HandleMap {
}
void deleteService(int serverIf, int serviceHandle) {
- for (Iterator<Entry> it = mEntries.iterator(); it.hasNext(); ) {
- Entry entry = it.next();
- if (entry.serverIf != serverIf) {
- continue;
- }
-
- if (entry.handle == serviceHandle || entry.serviceHandle == serviceHandle) {
- it.remove();
- }
- }
+ mEntries.removeIf(entry -> ((entry.serverIf == serverIf)
+ && (entry.handle == serviceHandle || entry.serviceHandle == serviceHandle)));
}
List<Entry> getEntries() {
diff --git a/android/app/src/com/android/bluetooth/gatt/ScanManager.java b/android/app/src/com/android/bluetooth/gatt/ScanManager.java
index 2aee8637bf..6494a6f448 100644
--- a/android/app/src/com/android/bluetooth/gatt/ScanManager.java
+++ b/android/app/src/com/android/bluetooth/gatt/ScanManager.java
@@ -95,7 +95,8 @@ public class ScanManager {
private BatchScanParams mBatchScanParms;
private Integer mCurUsedTrackableAdvertisements;
- private GattService mService;
+ private final GattService mService;
+ private final AdapterService mAdapterService;
private BroadcastReceiver mBatchAlarmReceiver;
private boolean mBatchAlarmReceiverRegistered;
private ScanNative mScanNative;
@@ -129,7 +130,7 @@ public class ScanManager {
}
}
- ScanManager(GattService service) {
+ ScanManager(GattService service, AdapterService adapterService) {
mRegularScanClients =
Collections.newSetFromMap(new ConcurrentHashMap<ScanClient, Boolean>());
mBatchClients = Collections.newSetFromMap(new ConcurrentHashMap<ScanClient, Boolean>());
@@ -141,6 +142,7 @@ public class ScanManager {
mDm = mService.getSystemService(DisplayManager.class);
mActivityManager = mService.getSystemService(ActivityManager.class);
mLocationManager = mService.getSystemService(LocationManager.class);
+ mAdapterService = adapterService;
mPriorityMap.put(ScanSettings.SCAN_MODE_OPPORTUNISTIC, 0);
mPriorityMap.put(ScanSettings.SCAN_MODE_SCREEN_OFF, 1);
@@ -383,7 +385,7 @@ public class ScanManager {
Message msg = obtainMessage(MSG_SCAN_TIMEOUT);
msg.obj = client;
// Only one timeout message should exist at any time
- sendMessageDelayed(msg, AppScanStats.getScanTimeoutMillis());
+ sendMessageDelayed(msg, mAdapterService.getScanTimeoutMillis());
}
}
}
@@ -547,7 +549,7 @@ public class ScanManager {
}
private boolean upgradeScanModeBeforeStart(ScanClient client) {
- if (client.started || AppScanStats.getScanUpgradeDurationMillis() == 0) {
+ if (client.started || mAdapterService.getScanUpgradeDurationMillis() == 0) {
return false;
}
if (client.stats == null || client.stats.hasRecentScan()) {
@@ -563,7 +565,7 @@ public class ScanManager {
if (DBG) {
Log.d(TAG, "scanMode is upgraded for " + client);
}
- sendMessageDelayed(msg, AppScanStats.getScanUpgradeDurationMillis());
+ sendMessageDelayed(msg, mAdapterService.getScanUpgradeDurationMillis());
return true;
}
return false;
diff --git a/android/app/src/com/android/bluetooth/hap/HapClientService.java b/android/app/src/com/android/bluetooth/hap/HapClientService.java
index 852bf67ea2..4a44daf8b7 100644
--- a/android/app/src/com/android/bluetooth/hap/HapClientService.java
+++ b/android/app/src/com/android/bluetooth/hap/HapClientService.java
@@ -20,14 +20,18 @@ package com.android.bluetooth.hap;
import static android.Manifest.permission.BLUETOOTH_CONNECT;
import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
+import static com.android.bluetooth.Utils.enforceBluetoothPrivilegedPermission;
+
import android.bluetooth.BluetoothCsipSetCoordinator;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHapClient;
import android.bluetooth.BluetoothHapPresetInfo;
import android.bluetooth.BluetoothLeAudio;
import android.bluetooth.BluetoothProfile;
+import android.bluetooth.BluetoothStatusCodes;
import android.bluetooth.BluetoothUuid;
import android.bluetooth.IBluetoothHapClient;
+import android.bluetooth.IBluetoothHapClientCallback;
import android.content.AttributionSource;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -35,6 +39,8 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.os.HandlerThread;
import android.os.ParcelUuid;
+import android.os.RemoteCallbackList;
+import android.os.RemoteException;
import android.util.Log;
import com.android.bluetooth.Utils;
@@ -48,6 +54,7 @@ import com.android.modules.utils.SynchronousResultReceiver;
import java.math.BigInteger;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
@@ -64,6 +71,7 @@ public class HapClientService extends ProfileService {
// Upper limit of all HearingAccess devices: Bonded or Connected
private static final int MAX_HEARING_ACCESS_STATE_MACHINES = 10;
+ private static final int SM_THREAD_JOIN_TIMEOUT_MS = 1000;
private static HapClientService sHapClient;
private final Map<BluetoothDevice, HapClientStateMachine> mStateMachines =
new HashMap<>();
@@ -76,10 +84,13 @@ public class HapClientService extends ProfileService {
private final Map<BluetoothDevice, Integer> mDeviceCurrentPresetMap = new HashMap<>();
private final Map<BluetoothDevice, Integer> mDeviceFeaturesMap = new HashMap<>();
- private final Map<BluetoothDevice, ArrayList<BluetoothHapPresetInfo>> mPresetsMap =
+ private final Map<BluetoothDevice, List<BluetoothHapPresetInfo>> mPresetsMap =
new HashMap<>();
@VisibleForTesting
+ RemoteCallbackList<IBluetoothHapClientCallback> mCallbacks;
+
+ @VisibleForTesting
ServiceFactory mFactory = new ServiceFactory();
private static synchronized void setHapClient(HapClientService instance) {
@@ -148,10 +159,6 @@ public class HapClientService extends ProfileService {
mStateMachinesThread = new HandlerThread("HapClientService.StateMachines");
mStateMachinesThread.start();
- mDeviceCurrentPresetMap.clear();
- mDeviceFeaturesMap.clear();
- mPresetsMap.clear();
-
// Setup broadcast receivers
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
@@ -162,12 +169,14 @@ public class HapClientService extends ProfileService {
mConnectionStateChangedReceiver = new ConnectionStateChangedReceiver();
registerReceiver(mConnectionStateChangedReceiver, filter, Context.RECEIVER_NOT_EXPORTED);
- // Mark service as started
- setHapClient(this);
+ mCallbacks = new RemoteCallbackList<IBluetoothHapClientCallback>();
// Initialize native interface
mHapClientNativeInterface.init();
+ // Mark service as started
+ setHapClient(this);
+
return true;
}
@@ -181,10 +190,6 @@ public class HapClientService extends ProfileService {
return true;
}
- // Cleanup GATT interface
- mHapClientNativeInterface.cleanup();
- mHapClientNativeInterface = null;
-
// Marks service as stopped
setHapClient(null);
@@ -203,13 +208,27 @@ public class HapClientService extends ProfileService {
mStateMachines.clear();
}
+ if (mStateMachinesThread != null) {
+ try {
+ mStateMachinesThread.quitSafely();
+ mStateMachinesThread.join(SM_THREAD_JOIN_TIMEOUT_MS);
+ mStateMachinesThread = null;
+ } catch (InterruptedException e) {
+ // Do not rethrow as we are shutting down anyway
+ }
+ }
+
+ // Cleanup GATT interface
+ mHapClientNativeInterface.cleanup();
+ mHapClientNativeInterface = null;
+
+ // Cleanup the internals
mDeviceCurrentPresetMap.clear();
mDeviceFeaturesMap.clear();
mPresetsMap.clear();
- if (mStateMachinesThread != null) {
- mStateMachinesThread.quitSafely();
- mStateMachinesThread = null;
+ if (mCallbacks != null) {
+ mCallbacks.kill();
}
// Clear AdapterService
@@ -340,8 +359,7 @@ public class HapClientService extends ProfileService {
* @return true on success, otherwise false
*/
public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) {
- enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
- "Need BLUETOOTH_PRIVILEGED permission");
+ enforceBluetoothPrivilegedPermission(this);
if (DBG) {
Log.d(TAG, "Saved connectionPolicy " + device + " = " + connectionPolicy);
}
@@ -432,8 +450,7 @@ public class HapClientService extends ProfileService {
* @return true if hearing access service client successfully connected, false otherwise
*/
public boolean connect(BluetoothDevice device) {
- enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
- "Need BLUETOOTH_PRIVILEGED permission");
+ enforceBluetoothPrivilegedPermission(this);
if (DBG) {
Log.d(TAG, "connect(): " + device);
}
@@ -469,8 +486,7 @@ public class HapClientService extends ProfileService {
* @return true if hearing access service client successfully disconnected, false otherwise
*/
public boolean disconnect(BluetoothDevice device) {
- enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
- "Need BLUETOOTH_PRIVILEGED permission");
+ enforceBluetoothPrivilegedPermission(this);
if (DBG) {
Log.d(TAG, "disconnect(): " + device);
}
@@ -537,12 +553,33 @@ public class HapClientService extends ProfileService {
* Gets the currently active preset index for a HA device
*
* @param device is the device for which we want to get the currently active preset
- * @return true if valid request was sent, false otherwise
+ * @return active preset index
*/
- public boolean getActivePresetIndex(BluetoothDevice device) {
- notifyActivePresetIndex(device, mDeviceCurrentPresetMap.getOrDefault(device,
- BluetoothHapClient.PRESET_INDEX_UNAVAILABLE));
- return true;
+ public int getActivePresetIndex(BluetoothDevice device) {
+ return mDeviceCurrentPresetMap.getOrDefault(device,
+ BluetoothHapClient.PRESET_INDEX_UNAVAILABLE);
+ }
+
+ /**
+ * Gets the currently active preset info for a HA device
+ *
+ * @param device is the device for which we want to get the currently active preset info
+ * @return active preset info
+ */
+ public BluetoothHapPresetInfo getActivePresetInfo(BluetoothDevice device) {
+ int index = getActivePresetIndex(device);
+ if (index == BluetoothHapClient.PRESET_INDEX_UNAVAILABLE) return null;
+
+ List<BluetoothHapPresetInfo> current_presets = mPresetsMap.get(device);
+ if (current_presets != null) {
+ for (BluetoothHapPresetInfo preset : current_presets) {
+ if (preset.getIndex() == index) {
+ return preset;
+ }
+ }
+ }
+
+ return null;
}
/**
@@ -550,12 +587,25 @@ public class HapClientService extends ProfileService {
*
* @param device is the device for which we want to set the active preset
* @param presetIndex is an index of one of the available presets
- * @return true if valid request was sent, false otherwise
*/
- public boolean selectActivePreset(BluetoothDevice device, int presetIndex) {
- if (presetIndex == BluetoothHapClient.PRESET_INDEX_UNAVAILABLE) return false;
+ public void selectPreset(BluetoothDevice device, int presetIndex) {
+ if (presetIndex == BluetoothHapClient.PRESET_INDEX_UNAVAILABLE) {
+ if (mCallbacks != null) {
+ int n = mCallbacks.beginBroadcast();
+ for (int i = 0; i < n; i++) {
+ try {
+ mCallbacks.getBroadcastItem(i).onSelectActivePresetFailed(device,
+ BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX);
+ } catch (RemoteException e) {
+ continue;
+ }
+ }
+ mCallbacks.finishBroadcast();
+ }
+ return;
+ }
+
mHapClientNativeInterface.selectActivePreset(device, presetIndex);
- return true;
}
/**
@@ -563,64 +613,70 @@ public class HapClientService extends ProfileService {
*
* @param groupId is the device group identifier for which want to set the active preset
* @param presetIndex is an index of one of the available presets
- * @return true if valid group request was sent, false otherwise
*/
- public boolean groupSelectActivePreset(int groupId, int presetIndex) {
- if (presetIndex == BluetoothHapClient.PRESET_INDEX_UNAVAILABLE
- || groupId == BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
- return false;
+ public void selectPresetForGroup(int groupId, int presetIndex) {
+ int status = BluetoothStatusCodes.ERROR_UNKNOWN;
+
+ if ((presetIndex == BluetoothHapClient.PRESET_INDEX_UNAVAILABLE)
+ || (groupId == BluetoothCsipSetCoordinator.GROUP_ID_INVALID)) {
+ if (presetIndex == BluetoothHapClient.PRESET_INDEX_UNAVAILABLE) {
+ status = BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX;
+ } else {
+ status = BluetoothStatusCodes.ERROR_CSIP_INVALID_GROUP_ID;
+ }
+
+ if (mCallbacks != null) {
+ int n = mCallbacks.beginBroadcast();
+ for (int i = 0; i < n; i++) {
+ try {
+ mCallbacks.getBroadcastItem(i).onSelectActivePresetForGroupFailed(groupId,
+ BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX);
+ } catch (RemoteException e) {
+ continue;
+ }
+ }
+ mCallbacks.finishBroadcast();
+ }
+ return;
}
mHapClientNativeInterface.groupSelectActivePreset(groupId, presetIndex);
- return true;
}
/**
* Sets the next preset as a currently active preset for a HA device
*
* @param device is the device for which we want to set the active preset
- * @return true if valid request was sent, false otherwise
*/
- public boolean nextActivePreset(BluetoothDevice device) {
+ public void switchToNextPreset(BluetoothDevice device) {
mHapClientNativeInterface.nextActivePreset(device);
- return true;
}
/**
* Sets the next preset as a currently active preset for a HA device group
*
* @param groupId is the device group identifier for which want to set the active preset
- * @return true if valid group request was sent, false otherwise
*/
- public boolean groupNextActivePreset(int groupId) {
- if (groupId == BluetoothCsipSetCoordinator.GROUP_ID_INVALID) return false;
-
+ public void switchToNextPresetForGroup(int groupId) {
mHapClientNativeInterface.groupNextActivePreset(groupId);
- return true;
}
/**
* Sets the previous preset as a currently active preset for a HA device
*
* @param device is the device for which we want to set the active preset
- * @return true if valid request was sent, false otherwise
*/
- public boolean previousActivePreset(BluetoothDevice device) {
+ public void switchToPreviousPreset(BluetoothDevice device) {
mHapClientNativeInterface.previousActivePreset(device);
- return true;
}
/**
* Sets the previous preset as a currently active preset for a HA device group
*
* @param groupId is the device group identifier for which want to set the active preset
- * @return true if valid group request was sent, false otherwise
*/
- public boolean groupPreviousActivePreset(int groupId) {
- if (groupId == BluetoothCsipSetCoordinator.GROUP_ID_INVALID) return false;
-
+ public void switchToPreviousPresetForGroup(int groupId) {
mHapClientNativeInterface.groupPreviousActivePreset(groupId);
- return true;
}
/**
@@ -628,78 +684,241 @@ public class HapClientService extends ProfileService {
*
* @param device is the device for which we want to get the preset name
* @param presetIndex is an index of one of the available presets
- * @return true if valid request was sent, false otherwise
+ * @return a preset Info corresponding to the requested preset index
*/
- public boolean getPresetInfo(BluetoothDevice device, int presetIndex) {
- if (presetIndex == BluetoothHapClient.PRESET_INDEX_UNAVAILABLE) return false;
- mHapClientNativeInterface.getPresetInfo(device, presetIndex);
- return true;
+ public BluetoothHapPresetInfo getPresetInfo(BluetoothDevice device, int presetIndex) {
+ BluetoothHapPresetInfo defaultValue = new BluetoothHapPresetInfo.Builder().build();
+
+ if (presetIndex == BluetoothHapClient.PRESET_INDEX_UNAVAILABLE) return defaultValue;
+
+ List<BluetoothHapPresetInfo> current_presets = mPresetsMap.get(device);
+ if (current_presets != null) {
+ for (BluetoothHapPresetInfo preset : current_presets) {
+ if (preset.getIndex() == presetIndex) {
+ return preset;
+ }
+ }
+ }
+
+ return defaultValue;
}
/**
* Requests all presets info
*
* @param device is the device for which we want to get all presets info
- * @return true if request was processed, false otherwise
+ * @return a list of all presets Info
*/
- public boolean getAllPresetsInfo(BluetoothDevice device) {
+ public List<BluetoothHapPresetInfo> getAllPresetInfo(BluetoothDevice device) {
if (mPresetsMap.containsKey(device)) {
- notifyPresets(device, BluetoothHapClient.PRESET_INFO_REASON_ALL_PRESET_INFO,
- mPresetsMap.get(device));
- return true;
+ return mPresetsMap.get(device);
}
- return false;
+ return Collections.emptyList();
}
/**
* Requests features
*
* @param device is the device for which we want to get features
- * @return true if request was processed, false otherwise
+ * @return integer with feature bits set
*/
- public boolean getFeatures(BluetoothDevice device) {
+ public int getFeatures(BluetoothDevice device) {
if (mDeviceFeaturesMap.containsKey(device)) {
- notifyFeatures(device, mDeviceFeaturesMap.get(device));
- return true;
+ return mDeviceFeaturesMap.get(device);
}
- return false;
+ return 0x00;
}
- private void notifyPresets(BluetoothDevice device, int infoReason,
- ArrayList<BluetoothHapPresetInfo> presets) {
- Intent intent = null;
+ private int stackEventPresetInfoReasonToProfileStatus(int statusCode) {
+ switch (statusCode) {
+ case HapClientStackEvent.PRESET_INFO_REASON_ALL_PRESET_INFO:
+ return BluetoothStatusCodes.REASON_LOCAL_STACK_REQUEST;
+ case HapClientStackEvent.PRESET_INFO_REASON_PRESET_INFO_UPDATE:
+ return BluetoothStatusCodes.REASON_REMOTE_REQUEST;
+ case HapClientStackEvent.PRESET_INFO_REASON_PRESET_DELETED:
+ return BluetoothStatusCodes.REASON_REMOTE_REQUEST;
+ case HapClientStackEvent.PRESET_INFO_REASON_PRESET_AVAILABILITY_CHANGED:
+ return BluetoothStatusCodes.REASON_REMOTE_REQUEST;
+ case HapClientStackEvent.PRESET_INFO_REASON_PRESET_INFO_REQUEST_RESPONSE:
+ return BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST;
+ default:
+ return BluetoothStatusCodes.ERROR_UNKNOWN;
+ }
+ }
- intent = new Intent(BluetoothHapClient.ACTION_HAP_ON_PRESET_INFO);
- if (intent != null) {
- intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- intent.putExtra(BluetoothHapClient.EXTRA_HAP_PRESET_INFO_REASON, infoReason);
- intent.putParcelableArrayListExtra(BluetoothHapClient.EXTRA_HAP_PRESET_INFO, presets);
- sendBroadcast(intent, BLUETOOTH_PRIVILEGED);
+ private void notifyPresetInfoChanged(BluetoothDevice device, int infoReason) {
+ List current_presets = mPresetsMap.get(device);
+ if (current_presets == null) return;
+
+ if (mCallbacks != null) {
+ int n = mCallbacks.beginBroadcast();
+ for (int i = 0; i < n; i++) {
+ try {
+ mCallbacks.getBroadcastItem(i).onPresetInfoChanged(device, current_presets,
+ stackEventPresetInfoReasonToProfileStatus(infoReason));
+ } catch (RemoteException e) {
+ continue;
+ }
+ }
+ mCallbacks.finishBroadcast();
}
}
- private void notifyPresets(int groupId, int infoReason,
- ArrayList<BluetoothHapPresetInfo> presets) {
- Intent intent = null;
+ private void notifyPresetInfoForGroupChanged(int groupId, int infoReason) {
+ List<BluetoothDevice> all_group_devices = getGroupDevices(groupId);
+ for (BluetoothDevice dev : all_group_devices) {
+ notifyPresetInfoChanged(dev, infoReason);
+ }
+ }
- intent = new Intent(BluetoothHapClient.ACTION_HAP_ON_PRESET_INFO);
- if (intent != null) {
- intent.putExtra(BluetoothHapClient.EXTRA_HAP_GROUP_ID, groupId);
- intent.putExtra(BluetoothHapClient.EXTRA_HAP_PRESET_INFO_REASON, infoReason);
- intent.putParcelableArrayListExtra(BluetoothHapClient.EXTRA_HAP_PRESET_INFO, presets);
- sendBroadcast(intent, BLUETOOTH_PRIVILEGED);
+ private void notifyFeaturesAvailable(BluetoothDevice device, int features) {
+ if (mCallbacks != null) {
+ int n = mCallbacks.beginBroadcast();
+ for (int i = 0; i < n; i++) {
+ try {
+ mCallbacks.getBroadcastItem(i).onHapFeaturesAvailable(device, features);
+ } catch (RemoteException e) {
+ continue;
+ }
+ }
+ mCallbacks.finishBroadcast();
}
}
- private void notifyFeatures(BluetoothDevice device, int features) {
- Intent intent = null;
+ private void notifyActivePresetChanged(BluetoothDevice device, int presetIndex) {
+ if (mCallbacks != null) {
+ int n = mCallbacks.beginBroadcast();
+ for (int i = 0; i < n; i++) {
+ try {
+ mCallbacks.getBroadcastItem(i).onActivePresetChanged(device, presetIndex);
+ } catch (RemoteException e) {
+ continue;
+ }
+ }
+ mCallbacks.finishBroadcast();
+ }
+ }
- intent = new Intent(BluetoothHapClient.ACTION_HAP_ON_DEVICE_FEATURES);
- if (intent != null) {
- intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- intent.putExtra(BluetoothHapClient.EXTRA_HAP_FEATURES, features);
- sendBroadcast(intent, BLUETOOTH_PRIVILEGED);
+ private void notifyActivePresetChangedForGroup(int groupId, int presetIndex) {
+ List<BluetoothDevice> all_group_devices = getGroupDevices(groupId);
+ for (BluetoothDevice dev : all_group_devices) {
+ notifyActivePresetChanged(dev, presetIndex);
+ }
+ }
+
+ private int stackEventStatusToProfileStatus(int statusCode) {
+ switch (statusCode) {
+ case HapClientStackEvent.STATUS_SET_NAME_NOT_ALLOWED:
+ return BluetoothStatusCodes.ERROR_REMOTE_OPERATION_REJECTED;
+ case HapClientStackEvent.STATUS_OPERATION_NOT_SUPPORTED:
+ return BluetoothStatusCodes.ERROR_REMOTE_OPERATION_NOT_SUPPORTED;
+ case HapClientStackEvent.STATUS_OPERATION_NOT_POSSIBLE:
+ return BluetoothStatusCodes.ERROR_REMOTE_OPERATION_REJECTED;
+ case HapClientStackEvent.STATUS_INVALID_PRESET_NAME_LENGTH:
+ return BluetoothStatusCodes.ERROR_HAP_PRESET_NAME_TOO_LONG;
+ case HapClientStackEvent.STATUS_INVALID_PRESET_INDEX:
+ return BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX;
+ case HapClientStackEvent.STATUS_GROUP_OPERATION_NOT_SUPPORTED:
+ return BluetoothStatusCodes.ERROR_REMOTE_OPERATION_NOT_SUPPORTED;
+ case HapClientStackEvent.STATUS_PROCEDURE_ALREADY_IN_PROGRESS:
+ return BluetoothStatusCodes.ERROR_UNKNOWN;
+ default:
+ return BluetoothStatusCodes.ERROR_UNKNOWN;
+ }
+ }
+
+ private void notifySelectActivePresetFailed(BluetoothDevice device, int statusCode) {
+ if (mCallbacks != null) {
+ int n = mCallbacks.beginBroadcast();
+ for (int i = 0; i < n; i++) {
+ try {
+ mCallbacks.getBroadcastItem(i).onSelectActivePresetFailed(device,
+ stackEventStatusToProfileStatus(statusCode));
+ } catch (RemoteException e) {
+ continue;
+ }
+ }
+ mCallbacks.finishBroadcast();
+ }
+ }
+
+ private void notifySelectActivePresetForGroupFailed(int groupId, int statusCode) {
+ if (mCallbacks != null) {
+ int n = mCallbacks.beginBroadcast();
+ for (int i = 0; i < n; i++) {
+ try {
+ mCallbacks.getBroadcastItem(i).onSelectActivePresetForGroupFailed(groupId,
+ stackEventStatusToProfileStatus(statusCode));
+ } catch (RemoteException e) {
+ continue;
+ }
+ }
+ mCallbacks.finishBroadcast();
+ }
+ }
+
+ private void notifySetPresetNameFailed(BluetoothDevice device, int statusCode) {
+ if (mCallbacks != null) {
+ int n = mCallbacks.beginBroadcast();
+ for (int i = 0; i < n; i++) {
+ try {
+ mCallbacks.getBroadcastItem(i).onSetPresetNameFailed(device,
+ stackEventStatusToProfileStatus(statusCode));
+ } catch (RemoteException e) {
+ continue;
+ }
+ }
+ mCallbacks.finishBroadcast();
+ }
+ }
+
+ private void notifySetPresetNameForGroupFailed(int groupId, int statusCode) {
+ if (mCallbacks != null) {
+ int n = mCallbacks.beginBroadcast();
+ for (int i = 0; i < n; i++) {
+ try {
+ mCallbacks.getBroadcastItem(i).onSetPresetNameForGroupFailed(groupId,
+ stackEventStatusToProfileStatus(statusCode));
+ } catch (RemoteException e) {
+ continue;
+ }
+ }
+ mCallbacks.finishBroadcast();
+ }
+ }
+
+ private boolean isPresetIndexValid(BluetoothDevice device, int presetIndex) {
+ if (presetIndex == BluetoothHapClient.PRESET_INDEX_UNAVAILABLE) return false;
+
+ List<BluetoothHapPresetInfo> device_presets = mPresetsMap.get(device);
+ if (device_presets != null) {
+ for (BluetoothHapPresetInfo preset : device_presets) {
+ if (preset.getIndex() == presetIndex) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean isPresetIndexValid(int groupId, int presetIndex) {
+ List<BluetoothDevice> all_group_devices = getGroupDevices(groupId);
+ for (BluetoothDevice device : all_group_devices) {
+ if (!isPresetIndexValid(device, presetIndex)) return false;
}
+ return true;
+ }
+
+
+ private boolean isGroupIdValid(int groupId) {
+ if (groupId == BluetoothCsipSetCoordinator.GROUP_ID_INVALID) return false;
+
+ CsipSetCoordinatorService csipClient = mFactory.getCsipSetCoordinatorService();
+ if (csipClient != null) {
+ List<Integer> groups = csipClient.getAllGroupIds(BluetoothUuid.CAP);
+ return groups.contains(groupId);
+ }
+ return true;
}
/**
@@ -708,12 +927,27 @@ public class HapClientService extends ProfileService {
* @param device is the device for which we want to get the preset name
* @param presetIndex is an index of one of the available presets
* @param name is a new name for a preset
- * @return true if valid request was sent, false otherwise
*/
- public boolean setPresetName(BluetoothDevice device, int presetIndex, String name) {
- if (presetIndex == BluetoothHapClient.PRESET_INDEX_UNAVAILABLE) return false;
+ public void setPresetName(BluetoothDevice device, int presetIndex, String name) {
+ if (!isPresetIndexValid(device, presetIndex)) {
+ if (mCallbacks != null) {
+ int n = mCallbacks.beginBroadcast();
+ for (int i = 0; i < n; i++) {
+ try {
+ mCallbacks.getBroadcastItem(i).onSetPresetNameFailed(device,
+ BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX);
+ } catch (RemoteException e) {
+ continue;
+ }
+ }
+ mCallbacks.finishBroadcast();
+ }
+ return;
+ }
+ // WARNING: We should check cache if preset exists and is writable, but then we would still
+ // need a way to trigger this action with an invalid index or on a non-writable
+ // preset for tests purpose.
mHapClientNativeInterface.setPresetName(device, presetIndex, name);
- return true;
}
/**
@@ -722,13 +956,33 @@ public class HapClientService extends ProfileService {
* @param groupId is the device group identifier
* @param presetIndex is an index of one of the available presets
* @param name is a new name for a preset
- * @return true if valid request was sent, false otherwise
*/
- public boolean groupSetPresetName(int groupId, int presetIndex, String name) {
- if (groupId == BluetoothCsipSetCoordinator.GROUP_ID_INVALID) return false;
- if (presetIndex == BluetoothHapClient.PRESET_INDEX_UNAVAILABLE) return false;
+ public void setPresetNameForGroup(int groupId, int presetIndex, String name) {
+ int status = BluetoothStatusCodes.SUCCESS;
+
+ if (!isGroupIdValid(groupId)) {
+ status = BluetoothStatusCodes.ERROR_CSIP_INVALID_GROUP_ID;
+ }
+ if (!isPresetIndexValid(groupId, presetIndex)) {
+ status = BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX;
+ }
+ if (status != BluetoothStatusCodes.SUCCESS) {
+ if (mCallbacks != null) {
+ int n = mCallbacks.beginBroadcast();
+ for (int i = 0; i < n; i++) {
+ try {
+ mCallbacks.getBroadcastItem(i).onSetPresetNameForGroupFailed(groupId,
+ status);
+ } catch (RemoteException e) {
+ continue;
+ }
+ }
+ mCallbacks.finishBroadcast();
+ }
+ return;
+ }
+
mHapClientNativeInterface.groupSetPresetName(groupId, presetIndex, name);
- return true;
}
@Override
@@ -745,30 +999,16 @@ public class HapClientService extends ProfileService {
HapClientStackEvent.FEATURE_BIT_NUM_SYNCHRONIZATED_PRESETS);
}
- void notifyActivePresetIndex(BluetoothDevice device, int presetIndex) {
- Intent intent = new Intent(BluetoothHapClient.ACTION_HAP_ON_ACTIVE_PRESET);
- intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- intent.putExtra(BluetoothHapClient.EXTRA_HAP_PRESET_INDEX, presetIndex);
- sendBroadcast(intent, BLUETOOTH_PRIVILEGED);
- }
-
- void notifyActivePresetIndex(int groupId, int presetIndex) {
- Intent intent = new Intent(BluetoothHapClient.ACTION_HAP_ON_ACTIVE_PRESET);
- intent.putExtra(BluetoothHapClient.EXTRA_HAP_GROUP_ID, groupId);
- intent.putExtra(BluetoothHapClient.EXTRA_HAP_PRESET_INDEX, presetIndex);
- sendBroadcast(intent, BLUETOOTH_PRIVILEGED);
- }
-
void updateDevicePresetsCache(BluetoothDevice device, int infoReason,
- ArrayList<BluetoothHapPresetInfo> presets) {
+ List<BluetoothHapPresetInfo> presets) {
switch (infoReason) {
- case BluetoothHapClient.PRESET_INFO_REASON_ALL_PRESET_INFO:
+ case HapClientStackEvent.PRESET_INFO_REASON_ALL_PRESET_INFO:
mPresetsMap.put(device, presets);
break;
- case BluetoothHapClient.PRESET_INFO_REASON_PRESET_INFO_UPDATE:
- case BluetoothHapClient.PRESET_INFO_REASON_PRESET_AVAILABILITY_CHANGED:
- case BluetoothHapClient.PRESET_INFO_REASON_PRESET_INFO_REQUEST_RESPONSE: {
- ArrayList current_presets = mPresetsMap.get(device);
+ case HapClientStackEvent.PRESET_INFO_REASON_PRESET_INFO_UPDATE:
+ case HapClientStackEvent.PRESET_INFO_REASON_PRESET_AVAILABILITY_CHANGED:
+ case HapClientStackEvent.PRESET_INFO_REASON_PRESET_INFO_REQUEST_RESPONSE: {
+ List current_presets = mPresetsMap.get(device);
if (current_presets != null) {
ListIterator<BluetoothHapPresetInfo> iter = current_presets.listIterator();
for (BluetoothHapPresetInfo new_preset : presets) {
@@ -786,8 +1026,8 @@ public class HapClientService extends ProfileService {
}
break;
- case BluetoothHapClient.PRESET_INFO_REASON_PRESET_DELETED: {
- ArrayList current_presets = mPresetsMap.get(device);
+ case HapClientStackEvent.PRESET_INFO_REASON_PRESET_DELETED: {
+ List current_presets = mPresetsMap.get(device);
if (current_presets != null) {
ListIterator<BluetoothHapPresetInfo> iter = current_presets.listIterator();
for (BluetoothHapPresetInfo new_preset : presets) {
@@ -807,6 +1047,19 @@ public class HapClientService extends ProfileService {
}
}
+ private List<BluetoothDevice> getGroupDevices(int groupId) {
+ List<BluetoothDevice> devices = new ArrayList<>();
+
+ // TODO: Fix missing CSIS service API to decouple from LeAudioService
+ LeAudioService le_audio_service = mFactory.getLeAudioService();
+ if (le_audio_service != null) {
+ if (groupId != BluetoothLeAudio.GROUP_ID_INVALID) {
+ devices = le_audio_service.getGroupDevices(groupId);
+ }
+ }
+ return devices;
+ }
+
/**
* Handle messages from native (JNI) to Java
*
@@ -840,7 +1093,7 @@ public class HapClientService extends ProfileService {
if (device != null) {
mDeviceFeaturesMap.put(device, features);
- notifyFeatures(device, features);
+ notifyFeaturesAvailable(device, features);
}
} return;
@@ -850,36 +1103,25 @@ public class HapClientService extends ProfileService {
if (device != null) {
mDeviceCurrentPresetMap.put(device, currentPresetIndex);
- notifyActivePresetIndex(device, currentPresetIndex);
+ notifyActivePresetChanged(device, currentPresetIndex);
} else if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
- // TODO: Fix missing CSIS service API to decouple from LeAudioService
- LeAudioService le_audio_service = mFactory.getLeAudioService();
- if (le_audio_service != null) {
- int group_id = le_audio_service.getGroupId(device);
- if (group_id != BluetoothLeAudio.GROUP_ID_INVALID) {
- List<BluetoothDevice> all_group_devices =
- le_audio_service.getGroupDevices(group_id);
- for (BluetoothDevice dev : all_group_devices) {
- mDeviceCurrentPresetMap.put(dev, currentPresetIndex);
- }
- }
+ List<BluetoothDevice> all_group_devices = getGroupDevices(groupId);
+ for (BluetoothDevice dev : all_group_devices) {
+ mDeviceCurrentPresetMap.put(dev, currentPresetIndex);
}
- notifyActivePresetIndex(groupId, currentPresetIndex);
+ notifyActivePresetChangedForGroup(groupId, currentPresetIndex);
}
} return;
case (HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR): {
- int statusCode = stackEvent.valueInt1;
int groupId = stackEvent.valueInt2;
-
- intent = new Intent(BluetoothHapClient.ACTION_HAP_ON_ACTIVE_PRESET_SELECT_ERROR);
- intent.putExtra(BluetoothHapClient.EXTRA_HAP_STATUS_CODE, statusCode);
+ int statusCode = stackEvent.valueInt1;
if (device != null) {
- intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
+ notifySelectActivePresetFailed(device, statusCode);
} else if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
- intent.putExtra(BluetoothHapClient.EXTRA_HAP_GROUP_ID, groupId);
+ notifySelectActivePresetForGroupFailed(groupId, statusCode);
}
} break;
@@ -891,22 +1133,14 @@ public class HapClientService extends ProfileService {
if (device != null) {
updateDevicePresetsCache(device, infoReason, presets);
- notifyPresets(device, infoReason, presets);
+ notifyPresetInfoChanged(device, infoReason);
} else if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
- // TODO: Fix missing CSIS service API to decouple from LeAudioService
- LeAudioService le_audio_service = mFactory.getLeAudioService();
- if (le_audio_service != null) {
- int group_id = le_audio_service.getGroupId(device);
- if (group_id != BluetoothLeAudio.GROUP_ID_INVALID) {
- List<BluetoothDevice> all_group_devices =
- le_audio_service.getGroupDevices(group_id);
- for (BluetoothDevice dev : all_group_devices) {
- updateDevicePresetsCache(dev, infoReason, presets);
- }
- }
+ List<BluetoothDevice> all_group_devices = getGroupDevices(groupId);
+ for (BluetoothDevice dev : all_group_devices) {
+ updateDevicePresetsCache(dev, infoReason, presets);
}
- notifyPresets(groupId, infoReason, presets);
+ notifyPresetInfoForGroupChanged(groupId, infoReason);
}
} return;
@@ -914,33 +1148,18 @@ public class HapClientService extends ProfileService {
case (HapClientStackEvent.EVENT_TYPE_ON_PRESET_NAME_SET_ERROR): {
int statusCode = stackEvent.valueInt1;
int presetIndex = stackEvent.valueInt2;
-
- intent = new Intent(BluetoothHapClient.ACTION_HAP_ON_PRESET_NAME_SET_ERROR);
- intent.putExtra(BluetoothHapClient.EXTRA_HAP_PRESET_INDEX, presetIndex);
- intent.putExtra(BluetoothHapClient.EXTRA_HAP_STATUS_CODE, statusCode);
+ int groupId = stackEvent.valueInt3;
if (device != null) {
- intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- } else {
- int groupId = stackEvent.valueInt3;
- intent.putExtra(BluetoothHapClient.EXTRA_HAP_GROUP_ID, groupId);
+ notifySetPresetNameFailed(device, statusCode);
+ } else if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
+ notifySetPresetNameForGroupFailed(groupId, statusCode);
}
} break;
case (HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO_ERROR): {
- int statusCode = stackEvent.valueInt1;
- int presetIndex = stackEvent.valueInt2;
-
- intent = new Intent(BluetoothHapClient.ACTION_HAP_ON_PRESET_INFO_GET_ERROR);
- intent.putExtra(BluetoothHapClient.EXTRA_HAP_PRESET_INDEX, presetIndex);
- intent.putExtra(BluetoothHapClient.EXTRA_HAP_STATUS_CODE, statusCode);
-
- if (device != null) {
- intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- } else {
- int groupId = stackEvent.valueInt3;
- intent.putExtra(BluetoothHapClient.EXTRA_HAP_GROUP_ID, groupId);
- }
+ // Used only to report back on hidden API calls used for testing.
+ Log.d(TAG, stackEvent.toString());
} break;
default:
@@ -1009,36 +1228,6 @@ public class HapClientService extends ProfileService {
}
@Override
- public void connect(BluetoothDevice device, AttributionSource source,
- SynchronousResultReceiver receiver) {
- try {
- boolean defaultValue = false;
- HapClientService service = getService(source);
- if (service != null) {
- defaultValue = service.connect(device);
- }
- receiver.send(defaultValue);
- } catch (RuntimeException e) {
- receiver.propagateException(e);
- }
- }
-
- @Override
- public void disconnect(BluetoothDevice device, AttributionSource source,
- SynchronousResultReceiver receiver) {
- try {
- boolean defaultValue = false;
- HapClientService service = getService(source);
- if (service != null) {
- defaultValue = service.disconnect(device);
- }
- receiver.send(defaultValue);
- } catch (RuntimeException e) {
- receiver.propagateException(e);
- }
- }
-
- @Override
public void getConnectedDevices(AttributionSource source,
SynchronousResultReceiver receiver) {
try {
@@ -1117,7 +1306,7 @@ public class HapClientService extends ProfileService {
public void getActivePresetIndex(BluetoothDevice device, AttributionSource source,
SynchronousResultReceiver receiver) {
try {
- boolean defaultValue = false;
+ int defaultValue = BluetoothHapClient.PRESET_INDEX_UNAVAILABLE;
HapClientService service = getService(source);
if (service != null) {
defaultValue = service.getActivePresetIndex(device);
@@ -1129,13 +1318,13 @@ public class HapClientService extends ProfileService {
}
@Override
- public void getHapGroup(BluetoothDevice device, AttributionSource source,
- SynchronousResultReceiver receiver) {
+ public void getActivePresetInfo(BluetoothDevice device,
+ AttributionSource source, SynchronousResultReceiver receiver) {
try {
- int defaultValue = BluetoothCsipSetCoordinator.GROUP_ID_INVALID;
+ BluetoothHapPresetInfo defaultValue = null;
HapClientService service = getService(source);
if (service != null) {
- defaultValue = service.getHapGroup(device);
+ defaultValue = service.getActivePresetInfo(device);
}
receiver.send(defaultValue);
} catch (RuntimeException e) {
@@ -1144,13 +1333,13 @@ public class HapClientService extends ProfileService {
}
@Override
- public void selectActivePreset(BluetoothDevice device, int presetIndex,
- AttributionSource source, SynchronousResultReceiver receiver) {
+ public void getHapGroup(BluetoothDevice device, AttributionSource source,
+ SynchronousResultReceiver receiver) {
try {
- boolean defaultValue = false;
+ int defaultValue = BluetoothCsipSetCoordinator.GROUP_ID_INVALID;
HapClientService service = getService(source);
if (service != null) {
- defaultValue = service.selectActivePreset(device, presetIndex);
+ defaultValue = service.getHapGroup(device);
}
receiver.send(defaultValue);
} catch (RuntimeException e) {
@@ -1159,76 +1348,51 @@ public class HapClientService extends ProfileService {
}
@Override
- public void groupSelectActivePreset(int groupId, int presetIndex,
- AttributionSource source, SynchronousResultReceiver receiver) {
- try {
- boolean defaultValue = false;
- HapClientService service = getService(source);
- if (service != null) {
- defaultValue = service.groupSelectActivePreset(groupId, presetIndex);
- }
- receiver.send(defaultValue);
- } catch (RuntimeException e) {
- receiver.propagateException(e);
+ public void selectPreset(BluetoothDevice device, int presetIndex,
+ AttributionSource source) {
+ HapClientService service = getService(source);
+ if (service != null) {
+ service.selectPreset(device, presetIndex);
}
}
@Override
- public void nextActivePreset(BluetoothDevice device, AttributionSource source,
- SynchronousResultReceiver receiver) {
- try {
- boolean defaultValue = false;
- HapClientService service = getService(source);
- if (service != null) {
- defaultValue = service.nextActivePreset(device);
- }
- receiver.send(defaultValue);
- } catch (RuntimeException e) {
- receiver.propagateException(e);
+ public void selectPresetForGroup(int groupId, int presetIndex, AttributionSource source) {
+ HapClientService service = getService(source);
+ if (service != null) {
+ service.selectPresetForGroup(groupId, presetIndex);
}
}
@Override
- public void groupNextActivePreset(int groupId, AttributionSource source,
- SynchronousResultReceiver receiver) {
- try {
- boolean defaultValue = false;
- HapClientService service = getService(source);
- if (service != null) {
- defaultValue = service.groupNextActivePreset(groupId);
- }
- receiver.send(defaultValue);
- } catch (RuntimeException e) {
- receiver.propagateException(e);
+ public void switchToNextPreset(BluetoothDevice device, AttributionSource source) {
+ HapClientService service = getService(source);
+ if (service != null) {
+ service.switchToNextPreset(device);
}
}
@Override
- public void previousActivePreset(BluetoothDevice device, AttributionSource source,
- SynchronousResultReceiver receiver) {
- try {
- boolean defaultValue = false;
- HapClientService service = getService(source);
- if (service != null) {
- defaultValue = service.previousActivePreset(device);
- }
- receiver.send(defaultValue);
- } catch (RuntimeException e) {
- receiver.propagateException(e);
+ public void switchToNextPresetForGroup(int groupId, AttributionSource source) {
+ HapClientService service = getService(source);
+ if (service != null) {
+ service.switchToNextPresetForGroup(groupId);
}
}
@Override
- public void groupPreviousActivePreset(int groupId, AttributionSource source, SynchronousResultReceiver receiver) {
- try {
- boolean defaultValue = false;
- HapClientService service = getService(source);
- if (service != null) {
- defaultValue = service.groupPreviousActivePreset(groupId);
- }
- receiver.send(defaultValue);
- } catch (RuntimeException e) {
- receiver.propagateException(e);
+ public void switchToPreviousPreset(BluetoothDevice device, AttributionSource source) {
+ HapClientService service = getService(source);
+ if (service != null) {
+ service.switchToPreviousPreset(device);
+ }
+ }
+
+ @Override
+ public void switchToPreviousPresetForGroup(int groupId, AttributionSource source) {
+ HapClientService service = getService(source);
+ if (service != null) {
+ service.switchToPreviousPresetForGroup(groupId);
}
}
@@ -1236,7 +1400,7 @@ public class HapClientService extends ProfileService {
public void getPresetInfo(BluetoothDevice device, int presetIndex,
AttributionSource source, SynchronousResultReceiver receiver) {
try {
- boolean defaultValue = false;
+ BluetoothHapPresetInfo defaultValue = new BluetoothHapPresetInfo.Builder().build();
HapClientService service = getService(source);
if (service != null) {
defaultValue = service.getPresetInfo(device, presetIndex);
@@ -1248,12 +1412,13 @@ public class HapClientService extends ProfileService {
}
@Override
- public void getAllPresetsInfo(BluetoothDevice device, AttributionSource source, SynchronousResultReceiver receiver) {
+ public void getAllPresetInfo(BluetoothDevice device, AttributionSource source,
+ SynchronousResultReceiver receiver) {
try {
- boolean defaultValue = false;
+ List<BluetoothHapPresetInfo> defaultValue = new ArrayList<>();
HapClientService service = getService(source);
if (service != null) {
- defaultValue = service.getAllPresetsInfo(device);
+ defaultValue = service.getAllPresetInfo(device);
}
receiver.send(defaultValue);
} catch (RuntimeException e) {
@@ -1262,9 +1427,10 @@ public class HapClientService extends ProfileService {
}
@Override
- public void getFeatures(BluetoothDevice device, AttributionSource source, SynchronousResultReceiver receiver) {
+ public void getFeatures(BluetoothDevice device, AttributionSource source,
+ SynchronousResultReceiver receiver) {
try {
- boolean defaultValue = false;
+ int defaultValue = 0x00;
HapClientService service = getService(source);
if (service != null) {
defaultValue = service.getFeatures(device);
@@ -1277,29 +1443,51 @@ public class HapClientService extends ProfileService {
@Override
public void setPresetName(BluetoothDevice device, int presetIndex, String name,
+ AttributionSource source) {
+ HapClientService service = getService(source);
+ if (service != null) {
+ service.setPresetName(device, presetIndex, name);
+ }
+ }
+
+ @Override
+ public void setPresetNameForGroup(int groupId, int presetIndex, String name,
+ AttributionSource source) {
+ HapClientService service = getService(source);
+ if (service != null) {
+ service.setPresetNameForGroup(groupId, presetIndex, name);
+ }
+ }
+
+ @Override
+ public void registerCallback(IBluetoothHapClientCallback callback,
AttributionSource source, SynchronousResultReceiver receiver) {
+ HapClientService service = getService(source);
+ if (service == null) {
+ throw new IllegalStateException("Service is unavailable");
+ }
+
+ enforceBluetoothPrivilegedPermission(service);
try {
- boolean defaultValue = false;
- HapClientService service = getService(source);
- if (service != null) {
- defaultValue = service.setPresetName(device, presetIndex, name);
- }
- receiver.send(defaultValue);
+ service.mCallbacks.register(callback);
+ receiver.send(null);
} catch (RuntimeException e) {
receiver.propagateException(e);
}
}
@Override
- public void groupSetPresetName(int groupId, int presetIndex, String name,
+ public void unregisterCallback(IBluetoothHapClientCallback callback,
AttributionSource source, SynchronousResultReceiver receiver) {
+ HapClientService service = getService(source);
+ if (service == null) {
+ throw new IllegalStateException("Service is unavailable");
+ }
+
+ enforceBluetoothPrivilegedPermission(service);
try {
- boolean defaultValue = false;
- HapClientService service = getService(source);
- if (service != null) {
- defaultValue = service.groupSetPresetName(groupId, presetIndex, name);
- }
- receiver.send(defaultValue);
+ service.mCallbacks.unregister(callback);
+ receiver.send(null);
} catch (RuntimeException e) {
receiver.propagateException(e);
}
diff --git a/android/app/src/com/android/bluetooth/hap/HapClientStackEvent.java b/android/app/src/com/android/bluetooth/hap/HapClientStackEvent.java
index 278bb1a06f..e322f505f0 100644
--- a/android/app/src/com/android/bluetooth/hap/HapClientStackEvent.java
+++ b/android/app/src/com/android/bluetooth/hap/HapClientStackEvent.java
@@ -47,20 +47,15 @@ public class HapClientStackEvent {
static final int CONNECTION_STATE_DISCONNECTING = 3;
// Possible operation results
- static final int STATUS_SET_NAME_NOT_ALLOWED =
- IBluetoothHapClient.STATUS_SET_NAME_NOT_ALLOWED;
- static final int STATUS_OPERATION_NOT_SUPPORTED =
- IBluetoothHapClient.STATUS_OPERATION_NOT_SUPPORTED;
- static final int STATUS_OPERATION_NOT_POSSIBLE =
- IBluetoothHapClient.STATUS_OPERATION_NOT_POSSIBLE;
- static final int STATUS_INVALID_PRESET_NAME_LENGTH =
- IBluetoothHapClient.STATUS_INVALID_PRESET_NAME_LENGTH;
- static final int STATUS_INVALID_PRESET_INDEX =
- IBluetoothHapClient.STATUS_INVALID_PRESET_INDEX;
- static final int STATUS_GROUP_OPERATION_NOT_SUPPORTED =
- IBluetoothHapClient.STATUS_GROUP_OPERATION_NOT_SUPPORTED;
- static final int STATUS_PROCEDURE_ALREADY_IN_PROGRESS =
- IBluetoothHapClient.STATUS_PROCEDURE_ALREADY_IN_PROGRESS;
+ /* WARNING: Matches status codes defined in bta_has.h */
+ static final int STATUS_NO_ERROR = 0;
+ static final int STATUS_SET_NAME_NOT_ALLOWED = 1;
+ static final int STATUS_OPERATION_NOT_SUPPORTED = 2;
+ static final int STATUS_OPERATION_NOT_POSSIBLE = 3;
+ static final int STATUS_INVALID_PRESET_NAME_LENGTH = 4;
+ static final int STATUS_INVALID_PRESET_INDEX = 5;
+ static final int STATUS_GROUP_OPERATION_NOT_SUPPORTED = 6;
+ static final int STATUS_PROCEDURE_ALREADY_IN_PROGRESS = 7;
// Supported features
public static final int FEATURE_BIT_NUM_TYPE_MONAURAL =
@@ -77,16 +72,12 @@ public class HapClientStackEvent {
IBluetoothHapClient.FEATURE_BIT_NUM_WRITABLE_PRESETS;
// Preset Info notification reason
- public static final int PRESET_INFO_REASON_ALL_PRESET_INFO =
- IBluetoothHapClient.PRESET_INFO_REASON_ALL_PRESET_INFO;
- public static final int PRESET_INFO_REASON_PRESET_INFO_UPDATE =
- IBluetoothHapClient.PRESET_INFO_REASON_PRESET_INFO_UPDATE;
- public static final int PRESET_INFO_REASON_PRESET_DELETED =
- IBluetoothHapClient.PRESET_INFO_REASON_PRESET_DELETED;
- public static final int PRESET_INFO_REASON_PRESET_AVAILABILITY_CHANGED =
- IBluetoothHapClient.PRESET_INFO_REASON_PRESET_AVAILABILITY_CHANGED;
- public static final int PRESET_INFO_REASON_PRESET_INFO_REQUEST_RESPONSE =
- IBluetoothHapClient.PRESET_INFO_REASON_PRESET_INFO_REQUEST_RESPONSE;
+ /* WARNING: Matches status codes defined in bta_has.h */
+ public static final int PRESET_INFO_REASON_ALL_PRESET_INFO = 0;
+ public static final int PRESET_INFO_REASON_PRESET_INFO_UPDATE = 1;
+ public static final int PRESET_INFO_REASON_PRESET_DELETED = 2;
+ public static final int PRESET_INFO_REASON_PRESET_AVAILABILITY_CHANGED = 3;
+ public static final int PRESET_INFO_REASON_PRESET_INFO_REQUEST_RESPONSE = 4;
public int type;
public BluetoothDevice device;
@@ -207,6 +198,8 @@ public class HapClientStackEvent {
private String statusCodeValueToString(int value) {
switch (value) {
+ case STATUS_NO_ERROR:
+ return "STATUS_NO_ERROR";
case STATUS_SET_NAME_NOT_ALLOWED:
return "STATUS_SET_NAME_NOT_ALLOWED";
case STATUS_OPERATION_NOT_SUPPORTED:
@@ -222,7 +215,7 @@ public class HapClientStackEvent {
case STATUS_PROCEDURE_ALREADY_IN_PROGRESS:
return "STATUS_PROCEDURE_ALREADY_IN_PROGRESS";
default:
- return "UNKNOWN_STATUS_CODE";
+ return "ERROR_UNKNOWN";
}
}
diff --git a/android/app/src/com/android/bluetooth/hap/HapClientStateMachine.java b/android/app/src/com/android/bluetooth/hap/HapClientStateMachine.java
index 7f10decb19..62c9dd2d14 100644
--- a/android/app/src/com/android/bluetooth/hap/HapClientStateMachine.java
+++ b/android/app/src/com/android/bluetooth/hap/HapClientStateMachine.java
@@ -238,7 +238,7 @@ final class HapClientStateMachine extends StateMachine {
@Override
public boolean processMessage(Message message) {
- log("Disconnected process message(" + mDevice + "): " + messageWhatToString(
+ log("Disconnected: process message(" + mDevice + "): " + messageWhatToString(
message.what));
switch (message.what) {
@@ -343,7 +343,7 @@ final class HapClientStateMachine extends StateMachine {
@Override
public boolean processMessage(Message message) {
- log("Connecting process message(" + mDevice + "): "
+ log("Connecting: process message(" + mDevice + "): "
+ messageWhatToString(message.what));
switch (message.what) {
@@ -430,7 +430,7 @@ final class HapClientStateMachine extends StateMachine {
@Override
public boolean processMessage(Message message) {
- log("Disconnecting process message(" + mDevice + "): "
+ log("Disconnecting: process message(" + mDevice + "): "
+ messageWhatToString(message.what));
switch (message.what) {
@@ -530,7 +530,7 @@ final class HapClientStateMachine extends StateMachine {
@Override
public boolean processMessage(Message message) {
- log("Connected process message(" + mDevice + "): "
+ log("Connected: process message(" + mDevice + "): "
+ messageWhatToString(message.what));
switch (message.what) {
diff --git a/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java b/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java
index 4f4a45ad6b..8d4b6d32c9 100644
--- a/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java
+++ b/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java
@@ -61,6 +61,9 @@ public class HearingAidService extends ProfileService {
private static final boolean DBG = true;
private static final String TAG = "HearingAidService";
+ // Timeout for state machine thread join, to prevent potential ANR.
+ private static final int SM_THREAD_JOIN_TIMEOUT_MS = 1000;
+
// Upper limit of all HearingAid devices: Bonded or Connected
private static final int MAX_HEARING_AID_STATE_MACHINES = 10;
private static HearingAidService sHearingAidService;
@@ -189,8 +192,13 @@ public class HearingAidService extends ProfileService {
mHiSyncIdConnectedMap.clear();
if (mStateMachinesThread != null) {
- mStateMachinesThread.quitSafely();
- mStateMachinesThread = null;
+ try {
+ mStateMachinesThread.quitSafely();
+ mStateMachinesThread.join(SM_THREAD_JOIN_TIMEOUT_MS);
+ mStateMachinesThread = null;
+ } catch (InterruptedException e) {
+ // Do not rethrow as we are shutting down anyway
+ }
}
// Clear AdapterService, HearingAidNativeInterface
@@ -531,7 +539,10 @@ public class HearingAidService extends ProfileService {
.getProfileConnectionPolicy(device, BluetoothProfile.HEARING_AID);
}
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
void setVolume(int volume) {
+ enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
+ "Need BLUETOOTH_PRIVILEGED permission");
mHearingAidNativeInterface.setVolume(volume);
}
diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetService.java b/android/app/src/com/android/bluetooth/hfp/HeadsetService.java
index a1af96c9c8..01702c9ea4 100644
--- a/android/app/src/com/android/bluetooth/hfp/HeadsetService.java
+++ b/android/app/src/com/android/bluetooth/hfp/HeadsetService.java
@@ -100,6 +100,9 @@ public class HeadsetService extends ProfileService {
{BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_CONNECTED};
private static final int DIALING_OUT_TIMEOUT_MS = 10000;
+ // Timeout for state machine thread join, to prevent potential ANR.
+ private static final int SM_THREAD_JOIN_TIMEOUT_MS = 1000;
+
private int mMaxHeadsetConnections = 1;
private BluetoothDevice mActiveDevice;
private AdapterService mAdapterService;
@@ -237,8 +240,14 @@ public class HeadsetService extends ProfileService {
// Step 3: Destroy system interface
mSystemInterface.stop();
// Step 2: Stop handler thread
- mStateMachinesThread.quitSafely();
- mStateMachinesThread = null;
+ try {
+ mStateMachinesThread.quitSafely();
+ mStateMachinesThread.join(SM_THREAD_JOIN_TIMEOUT_MS);
+ mStateMachinesThread = null;
+ } catch (InterruptedException e) {
+ // Do not rethrow as we are shutting down anyway
+ }
+
mStateMachinesThreadHandler = null;
// Step 1: Clear
synchronized (mStateMachines) {
diff --git a/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java b/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
index 7b63700f47..4026b3913b 100644
--- a/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
+++ b/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
@@ -39,6 +39,7 @@ import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadsetClient;
+import android.bluetooth.BluetoothHeadsetClient.NetworkServiceState;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothUuid;
import android.bluetooth.hfp.BluetoothHfpProtoEnums;
@@ -359,6 +360,27 @@ public class HeadsetClientStateMachine extends StateMachine {
HfpClientConnectionService.onCallChanged(c.getDevice(), c);
}
+ private void sendNetworkStateChangedIntent(BluetoothDevice device) {
+ if (device == null) {
+ return;
+ }
+ NetworkServiceState networkServiceState = new NetworkServiceState(
+ device,
+ mIndicatorNetworkState == HeadsetClientHalConstants.NETWORK_STATE_AVAILABLE,
+ mOperatorName,
+ mIndicatorNetworkSignal,
+ mIndicatorNetworkType == HeadsetClientHalConstants.SERVICE_TYPE_ROAMING);
+
+ Intent intent =
+ new Intent(BluetoothHeadsetClient.ACTION_NETWORK_SERVICE_STATE_CHANGED);
+ intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
+ intent.putExtra(BluetoothHeadsetClient.EXTRA_NETWORK_SERVICE_STATE, networkServiceState);
+
+ mService.sendBroadcastMultiplePermissions(intent,
+ new String[] {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED},
+ Utils.getTempBroadcastOptions());
+ }
+
private boolean queryCallsStart() {
logD("queryCallsStart");
clearPendingAction();
@@ -1429,6 +1451,7 @@ public class HeadsetClientStateMachine extends StateMachine {
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device);
mService.sendBroadcast(intent, BLUETOOTH_CONNECT,
Utils.getTempAllowlistBroadcastOptions());
+ sendNetworkStateChangedIntent(event.device);
if (mIndicatorNetworkState
== HeadsetClientHalConstants.NETWORK_STATE_AVAILABLE) {
@@ -1448,6 +1471,7 @@ public class HeadsetClientStateMachine extends StateMachine {
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device);
mService.sendBroadcast(intent, BLUETOOTH_CONNECT,
Utils.getTempAllowlistBroadcastOptions());
+ sendNetworkStateChangedIntent(event.device);
break;
case StackEvent.EVENT_TYPE_NETWORK_SIGNAL:
mIndicatorNetworkSignal = event.valueInt;
@@ -1458,6 +1482,7 @@ public class HeadsetClientStateMachine extends StateMachine {
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device);
mService.sendBroadcast(intent, BLUETOOTH_CONNECT,
Utils.getTempAllowlistBroadcastOptions());
+ sendNetworkStateChangedIntent(event.device);
break;
case StackEvent.EVENT_TYPE_BATTERY_LEVEL:
mIndicatorBatteryLevel = event.valueInt;
@@ -1478,6 +1503,7 @@ public class HeadsetClientStateMachine extends StateMachine {
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device);
mService.sendBroadcast(intent, BLUETOOTH_CONNECT,
Utils.getTempAllowlistBroadcastOptions());
+ sendNetworkStateChangedIntent(event.device);
break;
case StackEvent.EVENT_TYPE_VR_STATE_CHANGED:
int oldState = mVoiceRecognitionActive;
diff --git a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
index a94a5687c1..6ac0a88ea8 100644
--- a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
+++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
@@ -66,6 +66,9 @@ public class LeAudioService extends ProfileService {
private static final boolean DBG = true;
private static final String TAG = "LeAudioService";
+ // Timeout for state machine thread join, to prevent potential ANR.
+ private static final int SM_THREAD_JOIN_TIMEOUT_MS = 1000;
+
// Upper limit of all LeAudio devices: Bonded or Connected
private static final int MAX_LE_AUDIO_STATE_MACHINES = 10;
private static LeAudioService sLeAudioService;
@@ -260,8 +263,13 @@ public class LeAudioService extends ProfileService {
}
if (mStateMachinesThread != null) {
- mStateMachinesThread.quitSafely();
- mStateMachinesThread = null;
+ try {
+ mStateMachinesThread.quitSafely();
+ mStateMachinesThread.join(SM_THREAD_JOIN_TIMEOUT_MS);
+ mStateMachinesThread = null;
+ } catch (InterruptedException e) {
+ // Do not rethrow as we are shutting down anyway
+ }
}
mAudioManager = null;
@@ -650,6 +658,14 @@ public class LeAudioService extends ProfileService {
boolean newSupportedByDeviceInput = (newSupportedAudioDirections
& AUDIO_DIRECTION_INPUT_BIT) != 0;
+ /*
+ * Do not update input if neither previous nor current device support input
+ */
+ if (!oldSupportedByDeviceInput && !newSupportedByDeviceInput) {
+ Log.d(TAG, "updateActiveInDevice: Device does not support input.");
+ return false;
+ }
+
if (device != null && mActiveAudioInDevice != null) {
int previousGroupId = getGroupId(mActiveAudioInDevice);
if (previousGroupId == groupId) {
@@ -660,20 +676,16 @@ public class LeAudioService extends ProfileService {
if (mActiveAudioInDevice.isConnected()) {
device = mActiveAudioInDevice;
}
+ } else {
+ /* Mark old group as no active */
+ LeAudioGroupDescriptor descriptor = mGroupDescriptors.get(previousGroupId);
+ descriptor.mIsActive = false;
}
}
BluetoothDevice previousInDevice = mActiveAudioInDevice;
/*
- * Do not update input if neither previous nor current device support input
- */
- if (!oldSupportedByDeviceInput && !newSupportedByDeviceInput) {
- Log.d(TAG, "updateActiveInDevice: Device does not support input.");
- return false;
- }
-
- /*
* Update input if:
* - Device changed
* OR
@@ -709,6 +721,14 @@ public class LeAudioService extends ProfileService {
boolean newSupportedByDeviceOutput = (newSupportedAudioDirections
& AUDIO_DIRECTION_OUTPUT_BIT) != 0;
+ /*
+ * Do not update output if neither previous nor current device support output
+ */
+ if (!oldSupportedByDeviceOutput && !newSupportedByDeviceOutput) {
+ Log.d(TAG, "updateActiveOutDevice: Device does not support output.");
+ return false;
+ }
+
if (device != null && mActiveAudioOutDevice != null) {
int previousGroupId = getGroupId(mActiveAudioOutDevice);
if (previousGroupId == groupId) {
@@ -719,20 +739,17 @@ public class LeAudioService extends ProfileService {
if (mActiveAudioOutDevice.isConnected()) {
device = mActiveAudioOutDevice;
}
+ } else {
+ Log.i(TAG, " Switching active group from " + previousGroupId + " to " + groupId);
+ /* Mark old group as no active */
+ LeAudioGroupDescriptor descriptor = mGroupDescriptors.get(previousGroupId);
+ descriptor.mIsActive = false;
}
}
BluetoothDevice previousOutDevice = mActiveAudioOutDevice;
/*
- * Do not update output if neither previous nor current device support output
- */
- if (!oldSupportedByDeviceOutput && !newSupportedByDeviceOutput) {
- Log.d(TAG, "updateActiveOutDevice: Device does not support output.");
- return false;
- }
-
- /*
* Update output if:
* - Device changed
* OR
@@ -762,14 +779,16 @@ public class LeAudioService extends ProfileService {
* Report the active devices change to the active device manager and the media framework.
* @param groupId id of group which devices should be updated
* @param newActiveContexts new active contexts for group of devices
+ * @param oldActiveContexts old active contexts for group of devices
+ * @param isActive if there is new active group
*/
private void updateActiveDevices(Integer groupId, Integer oldActiveContexts,
Integer newActiveContexts, boolean isActive) {
-
BluetoothDevice device = null;
- if (isActive)
+ if (isActive) {
device = getFirstDeviceFromGroup(groupId);
+ }
boolean outReplaced =
updateActiveOutDevice(device, groupId, oldActiveContexts, newActiveContexts);
diff --git a/android/app/src/com/android/bluetooth/mcp/McpService.java b/android/app/src/com/android/bluetooth/mcp/McpService.java
index 1da7da7858..2508b2f38f 100644
--- a/android/app/src/com/android/bluetooth/mcp/McpService.java
+++ b/android/app/src/com/android/bluetooth/mcp/McpService.java
@@ -26,6 +26,7 @@ import android.util.Log;
import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.ProfileService;
+import com.android.internal.annotations.VisibleForTesting;
import java.util.HashMap;
import java.util.Map;
@@ -41,7 +42,7 @@ public class McpService extends ProfileService {
private static McpService sMcpService;
- private static MediaControlProfile mGmcs;
+ private static MediaControlProfile sGmcs;
private Map<BluetoothDevice, Integer> mDeviceAuthorizations = new HashMap<>();
private Handler mHandler = new Handler(Looper.getMainLooper());
@@ -65,8 +66,13 @@ public class McpService extends ProfileService {
return sMcpService;
}
+ @VisibleForTesting
+ public static MediaControlProfile getMediaControlProfile() {
+ return sGmcs;
+ }
+
public static void setMediaControlProfileForTesting(MediaControlProfile mediaControlProfile) {
- mGmcs = mediaControlProfile;
+ sGmcs = mediaControlProfile;
}
@Override
@@ -94,11 +100,11 @@ public class McpService extends ProfileService {
// Mark service as started
setMcpService(this);
- if (mGmcs == null) {
+ if (sGmcs == null) {
// Initialize the Media Control Service Server
- mGmcs = new MediaControlProfile(this);
+ sGmcs = new MediaControlProfile(this);
// Requires this service to be already started thus we have to make it an async call
- mHandler.post(() -> mGmcs.init());
+ mHandler.post(() -> sGmcs.init());
}
return true;
@@ -115,8 +121,9 @@ public class McpService extends ProfileService {
return true;
}
- if (mGmcs != null) {
- mGmcs.cleanup();
+ if (sGmcs != null) {
+ sGmcs.cleanup();
+ sGmcs = null;
}
// Mark service as stopped
@@ -141,7 +148,7 @@ public class McpService extends ProfileService {
: BluetoothDevice.ACCESS_REJECTED;
mDeviceAuthorizations.put(device, authorization);
- mGmcs.onDeviceAuthorizationSet(device);
+ sGmcs.onDeviceAuthorizationSet(device);
}
public int getDeviceAuthorization(BluetoothDevice device) {
@@ -192,6 +199,6 @@ public class McpService extends ProfileService {
@Override
public void dump(StringBuilder sb) {
super.dump(sb);
- mGmcs.dump(sb);
+ sGmcs.dump(sb);
}
}
diff --git a/android/app/src/com/android/bluetooth/sap/SapServer.java b/android/app/src/com/android/bluetooth/sap/SapServer.java
index c838fa37dc..2514863434 100644
--- a/android/app/src/com/android/bluetooth/sap/SapServer.java
+++ b/android/app/src/com/android/bluetooth/sap/SapServer.java
@@ -93,6 +93,9 @@ public class SapServer extends Thread implements Callback {
private PendingIntent mPendingDiscIntent = null;
// Holds a reference to disconnect timeout intents
+ /* Timeout for the message handler thread join, to prevent potential ANR. */
+ private static final int HANDLER_THREAD_JOIN_TIMEOUT_MS = 1000;
+
/* We store the mMaxMessageSize, as we need a copy of it when the init. sequence completes */
private int mMaxMsgSize = 0;
/* keep track of the current RIL test mode */
@@ -498,7 +501,7 @@ public class SapServer extends Thread implements Callback {
if (mHandlerThread != null) {
try {
mHandlerThread.quitSafely();
- mHandlerThread.join();
+ mHandlerThread.join(HANDLER_THREAD_JOIN_TIMEOUT_MS);
mHandlerThread = null;
} catch (InterruptedException e) {
}
diff --git a/android/app/src/com/android/bluetooth/tbs/TbsGeneric.java b/android/app/src/com/android/bluetooth/tbs/TbsGeneric.java
index a590a51916..cc974cf5f8 100644
--- a/android/app/src/com/android/bluetooth/tbs/TbsGeneric.java
+++ b/android/app/src/com/android/bluetooth/tbs/TbsGeneric.java
@@ -18,15 +18,14 @@
package com.android.bluetooth.tbs;
import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothGatt;
-import android.bluetooth.BluetoothGattCharacteristic;
-import android.bluetooth.BluetoothGattDescriptor;
-import android.bluetooth.BluetoothGattServerCallback;
-import android.bluetooth.BluetoothGattService;
-import android.bluetooth.BluetoothLeCallControl;
import android.bluetooth.BluetoothLeCall;
+import android.bluetooth.BluetoothLeCallControl;
import android.bluetooth.IBluetoothLeCallControlCallback;
+import android.content.BroadcastReceiver;
+import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
+import android.media.AudioManager;
import android.net.Uri;
import android.os.ParcelUuid;
import android.os.RemoteException;
@@ -115,6 +114,28 @@ public class TbsGeneric {
private Bearer mForegroundBearer = null;
private int mLastRequestIdAssigned = 0;
private List<String> mUriSchemes = new ArrayList<>(Arrays.asList("tel"));
+ private Receiver mReceiver = null;
+ private int mStoredRingerMode = -1;
+
+ private final class Receiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
+ int ringerMode = intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1);
+
+ if (ringerMode < 0 || ringerMode == mStoredRingerMode) return;
+
+ mStoredRingerMode = ringerMode;
+
+ if (isSilentModeEnabled()) {
+ mTbsGatt.setSilentModeFlag();
+ } else {
+ mTbsGatt.clearSilentModeFlag();
+ }
+ }
+ }
+ };
public boolean init(TbsGatt tbsGatt) {
if (DBG) {
@@ -128,8 +149,32 @@ public class TbsGeneric {
return false;
}
- return mTbsGatt.init(ccid, UCI, mUriSchemes, true, true, DEFAULT_PROVIDER_NAME,
- DEFAULT_BEARER_TECHNOLOGY, mTbsGattCallback);
+ if (!mTbsGatt.init(ccid, UCI, mUriSchemes, true, true, DEFAULT_PROVIDER_NAME,
+ DEFAULT_BEARER_TECHNOLOGY, mTbsGattCallback)) {
+ Log.e(TAG, " TbsGatt init failed");
+ return false;
+ }
+
+ AudioManager mAudioManager = mTbsGatt.getContext()
+ .getSystemService(AudioManager.class);
+ if (mAudioManager == null) {
+ Log.w(TAG, " AudioManager is not available");
+ return true;
+ }
+
+ // read initial value of ringer mode
+ mStoredRingerMode = mAudioManager.getRingerMode();
+
+ if (isSilentModeEnabled()) {
+ mTbsGatt.setSilentModeFlag();
+ } else {
+ mTbsGatt.clearSilentModeFlag();
+ }
+
+ mReceiver = new Receiver();
+ mTbsGatt.getContext().registerReceiver(mReceiver,
+ new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION));
+ return true;
}
public void cleanup() {
@@ -138,11 +183,18 @@ public class TbsGeneric {
}
if (mTbsGatt != null) {
+ if (mReceiver != null) {
+ mTbsGatt.getContext().unregisterReceiver(mReceiver);
+ }
mTbsGatt.cleanup();
mTbsGatt = null;
}
}
+ private boolean isSilentModeEnabled() {
+ return mStoredRingerMode != AudioManager.RINGER_MODE_NORMAL;
+ }
+
private Bearer getBearerByToken(String token) {
synchronized (mBearerList) {
for (Bearer bearer : mBearerList) {
diff --git a/android/app/src/com/android/bluetooth/vc/VolumeControlNativeInterface.java b/android/app/src/com/android/bluetooth/vc/VolumeControlNativeInterface.java
index ee6fd37b26..0d2b0ec0af 100644
--- a/android/app/src/com/android/bluetooth/vc/VolumeControlNativeInterface.java
+++ b/android/app/src/com/android/bluetooth/vc/VolumeControlNativeInterface.java
@@ -154,7 +154,8 @@ public class VolumeControlNativeInterface {
sendMessageToService(event);
}
- private void onVolumeStateChanged(int volume, boolean mute, byte[] address) {
+ private void onVolumeStateChanged(int volume, boolean mute, byte[] address,
+ boolean isAutonomous) {
VolumeControlStackEvent event =
new VolumeControlStackEvent(
VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
@@ -162,6 +163,7 @@ public class VolumeControlNativeInterface {
event.valueInt1 = -1;
event.valueInt2 = volume;
event.valueBool1 = mute;
+ event.valueBool2 = isAutonomous;
if (DBG) {
Log.d(TAG, "onVolumeStateChanged: " + event);
@@ -169,7 +171,8 @@ public class VolumeControlNativeInterface {
sendMessageToService(event);
}
- private void onGroupVolumeStateChanged(int volume, boolean mute, int groupId) {
+ private void onGroupVolumeStateChanged(int volume, boolean mute, int groupId,
+ boolean isAutonomous) {
VolumeControlStackEvent event =
new VolumeControlStackEvent(
VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
@@ -177,6 +180,7 @@ public class VolumeControlNativeInterface {
event.valueInt1 = groupId;
event.valueInt2 = volume;
event.valueBool1 = mute;
+ event.valueBool2 = isAutonomous;
if (DBG) {
Log.d(TAG, "onGroupVolumeStateChanged: " + event);
diff --git a/android/app/src/com/android/bluetooth/vc/VolumeControlService.java b/android/app/src/com/android/bluetooth/vc/VolumeControlService.java
index d15a956211..f6a8e037dc 100644
--- a/android/app/src/com/android/bluetooth/vc/VolumeControlService.java
+++ b/android/app/src/com/android/bluetooth/vc/VolumeControlService.java
@@ -32,6 +32,8 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.media.AudioDeviceAttributes;
+import android.media.AudioDeviceInfo;
import android.media.AudioManager;
import android.os.HandlerThread;
import android.os.ParcelUuid;
@@ -54,14 +56,25 @@ public class VolumeControlService extends ProfileService {
private static final boolean DBG = false;
private static final String TAG = "VolumeControlService";
+ // Timeout for state machine thread join, to prevent potential ANR.
+ private static final int SM_THREAD_JOIN_TIMEOUT_MS = 1000;
+
// Upper limit of all VolumeControl devices: Bonded or Connected
private static final int MAX_VC_STATE_MACHINES = 10;
+ private static final int LE_AUDIO_MAX_VOL = 255;
+ private static final int LE_AUDIO_MIN_VOL = 0;
+
private static VolumeControlService sVolumeControlService;
private AdapterService mAdapterService;
private HandlerThread mStateMachinesThread;
private BluetoothDevice mPreviousAudioDevice;
+ private int mMusicMaxVolume = 0;
+ private int mMusicMinVolume = 0;
+ private int mVoiceCallMaxVolume = 0;
+ private int mVoiceCallMinVolume = 0;
+
@VisibleForTesting
VolumeControlNativeInterface mVolumeControlNativeInterface;
@VisibleForTesting
@@ -106,6 +119,11 @@ public class VolumeControlService extends ProfileService {
Objects.requireNonNull(mAudioManager,
"AudioManager cannot be null when VolumeControlService starts");
+ mMusicMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
+ mMusicMinVolume = mAudioManager.getStreamMinVolume(AudioManager.STREAM_MUSIC);
+ mVoiceCallMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL);
+ mVoiceCallMinVolume = mAudioManager.getStreamMinVolume(AudioManager.STREAM_VOICE_CALL);
+
// Start handler thread for state machines
mStateMachines.clear();
mStateMachinesThread = new HandlerThread("VolumeControlService.StateMachines");
@@ -164,8 +182,13 @@ public class VolumeControlService extends ProfileService {
if (mStateMachinesThread != null) {
- mStateMachinesThread.quitSafely();
- mStateMachinesThread = null;
+ try {
+ mStateMachinesThread.quitSafely();
+ mStateMachinesThread.join(SM_THREAD_JOIN_TIMEOUT_MS);
+ mStateMachinesThread = null;
+ } catch (InterruptedException e) {
+ // Do not rethrow as we are shutting down anyway
+ }
}
// Clear AdapterService, VolumeControlNativeInterface
@@ -422,18 +445,51 @@ public class VolumeControlService extends ProfileService {
}
void handleVolumeControlChanged(BluetoothDevice device, int groupId,
- int volume, boolean mute) {
- /* TODO handle volume change for group in case of unicast le audio
- * or per device in case of broadcast or simple remote controller.
- * Note: minimum volume is 0 and maximum 255.
- */
+ int volume, boolean mute, boolean isAutonomous) {
+ if (!isAutonomous) {
+ // If the change is triggered by Android device, the stream is already changed.
+ return;
+ }
+ // TODO: Handle the other arguments: device, groupId, mute.
+
+ int streamType = getBluetoothContextualVolumeStream();
+ mAudioManager.setStreamVolume(streamType, getDeviceVolume(streamType, volume),
+ AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_BLUETOOTH_ABS_VOLUME);
+ }
+
+ int getDeviceVolume(int streamType, int bleVolume) {
+ int bleMaxVolume = 255; // min volume is zero
+ int deviceMaxVolume = (streamType == AudioManager.STREAM_VOICE_CALL)
+ ? mVoiceCallMaxVolume : mMusicMaxVolume;
+ int deviceMinVolume = (streamType == AudioManager.STREAM_VOICE_CALL)
+ ? mVoiceCallMinVolume : mMusicMinVolume;
+
+ // TODO: Investigate what happens in classic BT when BT volume is changed to zero.
+ return (int) Math.floor(
+ (double) bleVolume * (deviceMaxVolume - deviceMinVolume) / bleMaxVolume);
+ }
+
+ // Copied from AudioService.getBluetoothContextualVolumeStream() and modified it.
+ int getBluetoothContextualVolumeStream() {
+ int mode = mAudioManager.getMode();
+ switch (mode) {
+ case AudioManager.MODE_IN_COMMUNICATION:
+ case AudioManager.MODE_IN_CALL:
+ return AudioManager.STREAM_VOICE_CALL;
+ case AudioManager.MODE_NORMAL:
+ default:
+ // other conditions will influence the stream type choice, read on...
+ break;
+ }
+ return AudioManager.STREAM_MUSIC;
}
void messageFromNative(VolumeControlStackEvent stackEvent) {
if (stackEvent.type == VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED) {
handleVolumeControlChanged(stackEvent.device, stackEvent.valueInt1,
- stackEvent.valueInt2, stackEvent.valueBool1);
+ stackEvent.valueInt2, stackEvent.valueBool1,
+ stackEvent.valueBool2);
return;
}
@@ -495,6 +551,14 @@ public class VolumeControlService extends ProfileService {
sm = VolumeControlStateMachine.make(device, this,
mVolumeControlNativeInterface, mStateMachinesThread.getLooper());
mStateMachines.put(device, sm);
+
+ mAudioManager.setDeviceVolumeBehavior(
+ new AudioDeviceAttributes(
+ AudioDeviceAttributes.ROLE_OUTPUT,
+ // Currently, TYPE_BLUETOOTH_A2DP is the only thing that works.
+ AudioDeviceInfo.TYPE_BLUETOOTH_A2DP,
+ ""),
+ AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
return sm;
}
}
diff --git a/android/app/src/com/android/bluetooth/vc/VolumeControlStackEvent.java b/android/app/src/com/android/bluetooth/vc/VolumeControlStackEvent.java
index c5d4aa336b..2750c7e694 100644
--- a/android/app/src/com/android/bluetooth/vc/VolumeControlStackEvent.java
+++ b/android/app/src/com/android/bluetooth/vc/VolumeControlStackEvent.java
@@ -37,6 +37,7 @@ public class VolumeControlStackEvent {
public int valueInt1;
public int valueInt2;
public boolean valueBool1;
+ public boolean valueBool2;
/* Might need more for other callbacks*/
VolumeControlStackEvent(int type) {
@@ -52,6 +53,7 @@ public class VolumeControlStackEvent {
result.append(", valueInt1:" + eventTypeValue1ToString(type, valueInt1));
result.append(", valueInt2:" + eventTypeValue2ToString(type, valueInt2));
result.append(", valueBool1:" + eventTypeValueBool1ToString(type, valueBool1));
+ result.append(", valueBool2:" + eventTypeValueBool2ToString(type, valueBool2));
result.append("}");
return result.toString();
}
@@ -124,4 +126,14 @@ public class VolumeControlStackEvent {
}
return Boolean.toString(value);
}
+
+ private static String eventTypeValueBool2ToString(int type, boolean value) {
+ switch (type) {
+ case EVENT_TYPE_VOLUME_STATE_CHANGED:
+ return "{isAutonomous:" + value + "}";
+ default:
+ break;
+ }
+ return Boolean.toString(value);
+ }
}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpStateMachineTest.java
index b38c8423c2..1a78d7c67c 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpStateMachineTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpStateMachineTest.java
@@ -122,6 +122,7 @@ public class A2dpStateMachineTest {
}
mA2dpStateMachine.doQuit();
mHandlerThread.quit();
+ mHandlerThread.join(TIMEOUT_MS);
TestUtils.clearAdapterService(mAdapterService);
}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java
index db3ae79763..42e93e5bd8 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java
@@ -8,6 +8,7 @@ import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothAssignedNumbers;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothHeadsetClient;
import android.bluetooth.BluetoothProfile;
import android.content.Intent;
import android.os.Bundle;
@@ -437,6 +438,85 @@ public class RemoteDevicesTest {
new Object[]{1, "WRONG", "WRONG"}));
}
+ @Test
+ public void testResetBatteryLevelOnHeadsetClientStateChange() {
+ int batteryLevel = 10;
+
+ // Verify that device property is null initially
+ Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1));
+
+ // Verify that updating battery level triggers ACTION_BATTERY_LEVEL_CHANGED intent
+ mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel);
+ verify(mAdapterService).sendBroadcast(mIntentArgument.capture(), mStringArgument.capture(),
+ any(Bundle.class));
+ verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument);
+ Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue());
+
+ // Verify that user can get battery level after the update
+ Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1));
+ Assert.assertEquals(mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(),
+ batteryLevel);
+
+ // Verify that resetting battery level changes it back to BluetoothDevice
+ // .BATTERY_LEVEL_UNKNOWN
+ mRemoteDevices.onHeadsetClientConnectionStateChanged(
+ getHeadsetClientConnectionStateChangedIntent(mDevice1,
+ BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_DISCONNECTED));
+
+ // Verify BATTERY_LEVEL_CHANGED intent is sent after first reset
+ verify(mAdapterService, times(2)).sendBroadcast(mIntentArgument.capture(),
+ mStringArgument.capture(), any(Bundle.class));
+ verifyBatteryLevelChangedIntent(mDevice1, BluetoothDevice.BATTERY_LEVEL_UNKNOWN,
+ mIntentArgument);
+ Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue());
+
+ // Verify value is reset in properties
+ Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1));
+ Assert.assertEquals(mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(),
+ BluetoothDevice.BATTERY_LEVEL_UNKNOWN);
+
+ // Verify that updating battery level triggers ACTION_BATTERY_LEVEL_CHANGED intent again
+ mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel);
+ verify(mAdapterService, times(3)).sendBroadcast(mIntentArgument.capture(),
+ mStringArgument.capture(), any(Bundle.class));
+ verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument);
+ Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue());
+
+ verifyNoMoreInteractions(mAdapterService);
+ }
+
+ @Test
+ public void testAGIndicatorParser_testCorrectValue() {
+ int batteryLevel = 3;
+
+ // Verify that device property is null initially
+ Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1));
+
+ // Verify that ACTION_AG_EVENT intent updates battery level
+ mRemoteDevices.onAgIndicatorValueChanged(
+ getAgIndicatorIntent(mDevice1, null, null, null, new Integer(batteryLevel), null));
+ verify(mAdapterService).sendBroadcast(mIntentArgument.capture(), mStringArgument.capture(),
+ any(Bundle.class));
+ verifyBatteryLevelChangedIntent(mDevice1,
+ RemoteDevices.batteryChargeIndicatorToPercentge(batteryLevel), mIntentArgument);
+ Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue());
+ }
+
+ @Test
+ public void testAgIndicatorParser_testWrongIndicatorId() {
+ int batteryLevel = 10;
+
+ // Verify that device property is null initially
+ Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1));
+
+ // Verify that ACTION_AG_EVENT intent updates battery level
+ mRemoteDevices.onAgIndicatorValueChanged(
+ getAgIndicatorIntent(mDevice1, new Integer(1), null, null, null, null));
+ verify(mAdapterService, never()).sendBroadcast(any(), anyString());
+ // Verify that device property is still null after invalid update
+ Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1));
+ }
+
private static void verifyBatteryLevelChangedIntent(BluetoothDevice device, int batteryLevel,
ArgumentCaptor<Intent> intentArgument) {
verifyBatteryLevelChangedIntent(device, batteryLevel, intentArgument.getValue());
@@ -492,4 +572,38 @@ public class RemoteDevicesTest {
list.add(0);
return list.toArray();
}
+
+ private static Intent getHeadsetClientConnectionStateChangedIntent(BluetoothDevice device,
+ int oldState, int newState) {
+ Intent intent = new Intent(BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED);
+ intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
+ intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, oldState);
+ intent.putExtra(BluetoothProfile.EXTRA_STATE, newState);
+ return intent;
+ }
+
+ private static Intent getAgIndicatorIntent(BluetoothDevice device, Integer networkStatus,
+ Integer networkStrength, Integer roaming, Integer batteryLevel, String operatorName) {
+ Intent intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT);
+ intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
+
+ if (networkStatus != null) {
+ intent.putExtra(BluetoothHeadsetClient.EXTRA_NETWORK_STATUS, networkStatus.intValue());
+ }
+ if (networkStrength != null) {
+ intent.putExtra(BluetoothHeadsetClient.EXTRA_NETWORK_SIGNAL_STRENGTH,
+ networkStrength.intValue());
+ }
+ if (roaming != null) {
+ intent.putExtra(BluetoothHeadsetClient.EXTRA_NETWORK_ROAMING, roaming.intValue());
+ }
+ if (batteryLevel != null) {
+ intent.putExtra(BluetoothHeadsetClient.EXTRA_BATTERY_LEVEL, batteryLevel.intValue());
+ }
+ if (operatorName != null) {
+ intent.putExtra(BluetoothHeadsetClient.EXTRA_OPERATOR_NAME, operatorName);
+ }
+
+ return intent;
+ }
}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientTest.java b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientTest.java
index 7589ff24ae..6d2f61b240 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientTest.java
@@ -24,8 +24,11 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.os.Binder;
import android.os.Looper;
import android.os.ParcelUuid;
+import android.os.RemoteException;
+import android.util.Log;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.MediumTest;
@@ -39,6 +42,7 @@ import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.ServiceFactory;
import com.android.bluetooth.btservice.storage.DatabaseManager;
import com.android.bluetooth.csip.CsipSetCoordinatorService;
+import com.android.bluetooth.le_audio.LeAudioService;
import org.junit.After;
import org.junit.Assert;
@@ -47,13 +51,16 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeoutException;
@@ -69,9 +76,9 @@ public class HapClientTest {
private BluetoothDevice mDevice3;
private Context mTargetContext;
private HapClientService mService;
- private IBluetoothHapClient.Stub mServiceBinder;
private HasIntentReceiver mHasIntentReceiver;
private HashMap<BluetoothDevice, LinkedBlockingQueue<Intent>> mIntentQueue;
+
@Mock
private AdapterService mAdapterService;
@Mock
@@ -82,6 +89,12 @@ public class HapClientTest {
private ServiceFactory mServiceFactory;
@Mock
private CsipSetCoordinatorService mCsipService;
+ @Mock
+ private LeAudioService mLeAudioService;
+ @Mock
+ private IBluetoothHapClientCallback mCallback;
+ @Mock
+ private Binder mBinder;
@Before
public void setUp() throws Exception {
@@ -96,6 +109,8 @@ public class HapClientTest {
Looper.prepare();
}
+ HapClientStateMachine.sConnectTimeoutMs = TIMEOUT_MS;
+
TestUtils.setAdapterService(mAdapterService);
doReturn(mDatabaseManager).when(mAdapterService).getDatabase();
doReturn(true, false).when(mAdapterService).isStartedProfile(anyString());
@@ -106,18 +121,15 @@ public class HapClientTest {
mService.mHapClientNativeInterface = mNativeInterface;
mService.mFactory = mServiceFactory;
doReturn(mCsipService).when(mServiceFactory).getCsipSetCoordinatorService();
- mServiceBinder = (IBluetoothHapClient.Stub) mService.initBinder();
- Assert.assertNotNull(mServiceBinder);
+ doReturn(mLeAudioService).when(mServiceFactory).getLeAudioService();
// Set up the State Changed receiver
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothHapClient.ACTION_HAP_DEVICE_AVAILABLE);
- filter.addAction(BluetoothHapClient.ACTION_HAP_ON_ACTIVE_PRESET);
- filter.addAction(BluetoothHapClient.ACTION_HAP_ON_ACTIVE_PRESET_SELECT_ERROR);
- filter.addAction(BluetoothHapClient.ACTION_HAP_ON_PRESET_INFO);
- filter.addAction(BluetoothHapClient.ACTION_HAP_ON_PRESET_NAME_SET_ERROR);
- filter.addAction(BluetoothHapClient.ACTION_HAP_ON_PRESET_INFO_GET_ERROR);
+
+ when(mCallback.asBinder()).thenReturn(mBinder);
+ mService.mCallbacks.register(mCallback);
mHasIntentReceiver = new HasIntentReceiver();
mTargetContext.registerReceiver(mHasIntentReceiver, filter);
@@ -129,6 +141,27 @@ public class HapClientTest {
mDevice3 = TestUtils.getTestDevice(mAdapter, 2);
when(mNativeInterface.getDevice(getByteAddress(mDevice3))).thenReturn(mDevice3);
+ /* Prepare CAS groups */
+ doReturn(Arrays.asList(0x02, 0x03)).when(mCsipService).getAllGroupIds(BluetoothUuid.CAP);
+
+ int groupId2 = 0x02;
+ Map groups2 = new HashMap<Integer, ParcelUuid>();
+ groups2.put(groupId2, ParcelUuid.fromString("00001853-0000-1000-8000-00805F9B34FB"));
+
+ int groupId3 = 0x03;
+ Map groups3 = new HashMap<Integer, ParcelUuid>();
+ groups3.put(groupId3,
+ ParcelUuid.fromString("00001853-0000-1000-8000-00805F9B34FB"));
+
+ doReturn(Arrays.asList(mDevice, mDevice2)).when(mLeAudioService).getGroupDevices(groupId2);
+ doReturn(groups2).when(mCsipService).getGroupUuidMapByDevice(mDevice);
+ doReturn(groups2).when(mCsipService).getGroupUuidMapByDevice(mDevice2);
+
+ doReturn(Arrays.asList(mDevice3)).when(mLeAudioService).getGroupDevices(0x03);
+ doReturn(groups3).when(mCsipService).getGroupUuidMapByDevice(mDevice3);
+
+ doReturn(Arrays.asList(mDevice)).when(mLeAudioService).getGroupDevices(0x01);
+
doReturn(BluetoothDevice.BOND_BONDED).when(mAdapterService)
.getBondState(any(BluetoothDevice.class));
doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService)
@@ -147,8 +180,12 @@ public class HapClientTest {
R.bool.profile_supported_hap_client)) {
return;
}
+ mService.mCallbacks.unregister(mCallback);
+
stopService();
mTargetContext.unregisterReceiver(mHasIntentReceiver);
+
+ mAdapter = null;
TestUtils.clearAdapterService(mAdapterService);
mIntentQueue.clear();
}
@@ -169,7 +206,7 @@ public class HapClientTest {
* Test getting HA Service Client
*/
@Test
- public void testGetHearingAidService() {
+ public void testGetHapService() {
Assert.assertEquals(mService, HapClientService.getHapClientService());
}
@@ -177,7 +214,7 @@ public class HapClientTest {
* Test stop HA Service Client
*/
@Test
- public void testStopHearingAidService() {
+ public void testStopHapService() {
Assert.assertEquals(mService, HapClientService.getHapClientService());
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
@@ -371,14 +408,8 @@ public class HapClientTest {
*/
@Test
public void testCallsForNotConnectedDevice() {
- Assert.assertEquals(true, mService.getActivePresetIndex(mDevice));
-
- Intent intent = TestUtils.waitForIntent(TIMEOUT_MS, mIntentQueue.get(mDevice));
- Assert.assertNotNull(intent);
- Assert.assertEquals(BluetoothHapClient.ACTION_HAP_ON_ACTIVE_PRESET, intent.getAction());
- Assert.assertEquals(mDevice, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE));
Assert.assertEquals(BluetoothHapClient.PRESET_INDEX_UNAVAILABLE,
- intent.getIntExtra(BluetoothHapClient.EXTRA_HAP_PRESET_INDEX, -1));
+ mService.getActivePresetIndex(mDevice));
}
/**
@@ -395,51 +426,45 @@ public class HapClientTest {
int flags = 0x04;
mNativeInterface.onFeaturesUpdate(getByteAddress(mDevice), flags);
- int flags2 = 0x04;
- mNativeInterface.onFeaturesUpdate(getByteAddress(mDevice2), flags);
+ int flags3 = 0x04;
+ mNativeInterface.onFeaturesUpdate(getByteAddress(mDevice3), flags);
/* This one has no coordinated operation support but is part of a coordinated set with
* mDevice, which supports it, thus mDevice will forward the operation to mDevice2.
* This device should also be rocognised as grouped one.
*/
- int flags3 = 0;
- mNativeInterface.onFeaturesUpdate(getByteAddress(mDevice3), flags3);
+ int flags2 = 0;
+ mNativeInterface.onFeaturesUpdate(getByteAddress(mDevice2), flags2);
- /* Prepare CAS groups */
- int base_group_id = 0x03;
- Map groups = new HashMap<Integer, ParcelUuid>();
- groups.put(base_group_id, ParcelUuid.fromString("00001853-0000-1000-8000-00805F9B34FB"));
-
- Map groups2 = new HashMap<Integer, ParcelUuid>();
- groups2.put(base_group_id + 1,
- ParcelUuid.fromString("00001853-0000-1000-8000-00805F9B34FB"));
-
- doReturn(groups).when(mCsipService).getGroupUuidMapByDevice(mDevice);
- doReturn(groups).when(mCsipService).getGroupUuidMapByDevice(mDevice3);
- doReturn(groups2).when(mCsipService).getGroupUuidMapByDevice(mDevice2);
-
- /* Two devices support coordinated operations thus shell report valid group ID */
- Assert.assertEquals(base_group_id, mService.getHapGroup(mDevice));
- Assert.assertEquals(base_group_id + 1, mService.getHapGroup(mDevice2));
+ /* Two devices support coordinated operations thus shall report valid group ID */
+ Assert.assertEquals(2, mService.getHapGroup(mDevice));
+ Assert.assertEquals(3, mService.getHapGroup(mDevice3));
/* Third one has no coordinated operations support but is part of the group */
- Assert.assertEquals(base_group_id, mService.getHapGroup(mDevice3));
+ Assert.assertEquals(2, mService.getHapGroup(mDevice2));
}
/**
- * Test that selectActivePreset properly calls the native method.
+ * Test that selectPreset properly calls the native method.
*/
@Test
- public void testSelectActivePresetNative() {
+ public void testSelectPresetNative() {
doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService)
.getRemoteUuids(any(BluetoothDevice.class));
testConnectingDevice(mDevice);
// Verify Native Interface call
- Assert.assertFalse(mService.selectActivePreset(mDevice, 0x00));
+ mService.selectPreset(mDevice, 0x00);
verify(mNativeInterface, times(0))
.selectActivePreset(eq(mDevice), eq(0x00));
- Assert.assertTrue(mService.selectActivePreset(mDevice, 0x01));
+ try {
+ verify(mCallback, after(TIMEOUT_MS).times(1)).onSelectActivePresetFailed(eq(mDevice),
+ eq(BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
+ mService.selectPreset(mDevice, 0x01);
verify(mNativeInterface, times(1))
.selectActivePreset(eq(mDevice), eq(0x01));
}
@@ -455,8 +480,15 @@ public class HapClientTest {
mNativeInterface.onFeaturesUpdate(getByteAddress(mDevice), flags);
// Verify Native Interface call
- Assert.assertFalse(mService.groupSelectActivePreset(0x03, 0x00));
- Assert.assertTrue(mService.groupSelectActivePreset(0x03, 0x01));
+ mService.selectPresetForGroup(0x03, 0x00);
+ try {
+ verify(mCallback, after(TIMEOUT_MS).times(1)).onSelectActivePresetForGroupFailed(
+ eq(0x03), eq(BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
+ mService.selectPresetForGroup(0x03, 0x01);
verify(mNativeInterface, times(1))
.groupSelectActivePreset(eq(0x03), eq(0x01));
}
@@ -465,13 +497,13 @@ public class HapClientTest {
* Test that nextActivePreset properly calls the native method.
*/
@Test
- public void testNextActivePresetNative() {
+ public void testSwitchToNextPreset() {
doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService)
.getRemoteUuids(any(BluetoothDevice.class));
testConnectingDevice(mDevice);
// Verify Native Interface call
- Assert.assertTrue(mService.nextActivePreset(mDevice));
+ mService.switchToNextPreset(mDevice);
verify(mNativeInterface, times(1))
.nextActivePreset(eq(mDevice));
}
@@ -480,14 +512,14 @@ public class HapClientTest {
* Test that groupNextActivePreset properly calls the native method.
*/
@Test
- public void testGroupNextActivePresetNative() {
+ public void testSwitchToNextPresetForGroup() {
doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService)
.getRemoteUuids(any(BluetoothDevice.class));
int flags = 0x01;
mNativeInterface.onFeaturesUpdate(getByteAddress(mDevice), flags);
// Verify Native Interface call
- Assert.assertTrue(mService.groupNextActivePreset(0x03));
+ mService.switchToNextPresetForGroup(0x03);
verify(mNativeInterface, times(1)).groupNextActivePreset(eq(0x03));
}
@@ -495,13 +527,13 @@ public class HapClientTest {
* Test that previousActivePreset properly calls the native method.
*/
@Test
- public void testPreviousActivePresetNative() {
+ public void testSwitchToPreviousPreset() {
doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService)
.getRemoteUuids(any(BluetoothDevice.class));
testConnectingDevice(mDevice);
// Verify Native Interface call
- Assert.assertTrue(mService.previousActivePreset(mDevice));
+ mService.switchToPreviousPreset(mDevice);
verify(mNativeInterface, times(1))
.previousActivePreset(eq(mDevice));
}
@@ -510,7 +542,7 @@ public class HapClientTest {
* Test that groupPreviousActivePreset properly calls the native method.
*/
@Test
- public void testGroupPreviousActivePresetNative() {
+ public void testSwitchToPreviousPresetForGroup() {
doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService)
.getRemoteUuids(any(BluetoothDevice.class));
testConnectingDevice(mDevice);
@@ -520,7 +552,7 @@ public class HapClientTest {
mNativeInterface.onFeaturesUpdate(getByteAddress(mDevice), flags);
// Verify Native Interface call
- Assert.assertTrue(mService.groupPreviousActivePreset(0x03));
+ mService.switchToPreviousPresetForGroup(0x03);
verify(mNativeInterface, times(1)).groupPreviousActivePreset(eq(0x03));
}
@@ -532,39 +564,38 @@ public class HapClientTest {
doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService)
.getRemoteUuids(any(BluetoothDevice.class));
testConnectingDevice(mDevice);
- testOnActivePresetSelected(mDevice, 0x01);
+ testOnActivePresetChanged(mDevice, 0x01);
// Verify cached value
- Assert.assertEquals(true, mService.getActivePresetIndex(mDevice));
-
- Intent intent = TestUtils.waitForIntent(TIMEOUT_MS, mIntentQueue.get(mDevice));
- Assert.assertNotNull(intent);
- Assert.assertEquals(BluetoothHapClient.ACTION_HAP_ON_ACTIVE_PRESET, intent.getAction());
- Assert.assertEquals(mDevice, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE));
- Assert.assertEquals(0x01,
- intent.getIntExtra(BluetoothHapClient.EXTRA_HAP_PRESET_INDEX, -1));
+ Assert.assertEquals(0x01, mService.getActivePresetIndex(mDevice));
}
/**
- * Test that getPresetInfo properly calls the native method.
+ * Test that getActivePresetInfo returns cached value for valid parameters.
*/
@Test
- public void testGetPresetInfoNative() {
+ public void testGetActivePresetInfo() {
doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService)
.getRemoteUuids(any(BluetoothDevice.class));
- testConnectingDevice(mDevice);
+ testConnectingDevice(mDevice2);
- // Verify Native Interface call
- Assert.assertFalse(mService.getPresetInfo(mDevice, 0x00));
- verify(mNativeInterface, times(0))
- .getPresetInfo(eq(mDevice), eq(0x00));
- Assert.assertTrue(mService.getPresetInfo(mDevice, 0x01));
- verify(mNativeInterface, times(1))
- .getPresetInfo(eq(mDevice), eq(0x01));
+ // Check when active preset is not known yet
+ Assert.assertEquals(BluetoothHapClient.PRESET_INDEX_UNAVAILABLE,
+ mService.getActivePresetIndex(mDevice2));
+ Assert.assertEquals(null, mService.getActivePresetInfo(mDevice2));
+
+ // Inject active preset change event
+ testOnActivePresetChanged(mDevice2, 0x01);
+
+ // Check when active preset is known
+ Assert.assertEquals(0x01, mService.getActivePresetIndex(mDevice2));
+ BluetoothHapPresetInfo info = mService.getActivePresetInfo(mDevice2);
+ Assert.assertNotNull(info);
+ Assert.assertEquals(0x01, info.getIndex());
}
/**
- * Test that setPresetName properly calls the native method.
+ * Test that setPresetName properly calls the native method for the valid parameters.
*/
@Test
public void testSetPresetNameNative() {
@@ -572,31 +603,57 @@ public class HapClientTest {
.getRemoteUuids(any(BluetoothDevice.class));
testConnectingDevice(mDevice);
- // Verify Native Interface call
- Assert.assertFalse(mService.setPresetName(mDevice, 0x00, "ExamplePresetName"));
+ mService.setPresetName(mDevice, 0x00, "ExamplePresetName");
verify(mNativeInterface, times(0))
.setPresetName(eq(mDevice), eq(0x00), eq("ExamplePresetName"));
- Assert.assertTrue(mService.setPresetName(mDevice, 0x01, "ExamplePresetName"));
+ try {
+ verify(mCallback, after(TIMEOUT_MS).times(1)).onSetPresetNameFailed(eq(mDevice),
+ eq(BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
+ // Verify Native Interface call
+ mService.setPresetName(mDevice, 0x01, "ExamplePresetName");
verify(mNativeInterface, times(1))
.setPresetName(eq(mDevice), eq(0x01), eq("ExamplePresetName"));
}
/**
- * Test that groupSetPresetName properly calls the native method.
+ * Test that setPresetNameForGroup properly calls the native method for the valid parameters.
*/
@Test
- public void testGroupSetPresetName() {
+ public void testSetPresetNameForGroup() {
doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService)
.getRemoteUuids(any(BluetoothDevice.class));
+ int test_group = 0x02;
+ for (BluetoothDevice device : mLeAudioService.getGroupDevices(test_group)) {
+ testConnectingDevice(device);
+ }
+
int flags = 0x21;
mNativeInterface.onFeaturesUpdate(getByteAddress(mDevice), flags);
+ mService.setPresetNameForGroup(test_group, 0x00, "ExamplePresetName");
+ try {
+ verify(mCallback, after(TIMEOUT_MS).times(1)).onSetPresetNameForGroupFailed(eq(test_group),
+ eq(BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
+ mService.setPresetNameForGroup(-1, 0x01, "ExamplePresetName");
+ try {
+ verify(mCallback, after(TIMEOUT_MS).times(1)).onSetPresetNameForGroupFailed(eq(-1),
+ eq(BluetoothStatusCodes.ERROR_CSIP_INVALID_GROUP_ID));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
// Verify Native Interface call
- Assert.assertFalse(mService.groupSetPresetName(0x03, 0x00, "ExamplePresetName"));
- Assert.assertFalse(mService.groupSetPresetName(-1, 0x01, "ExamplePresetName"));
- Assert.assertTrue(mService.groupSetPresetName(0x03, 0x01, "ExamplePresetName"));
+ mService.setPresetNameForGroup(test_group, 0x01, "ExamplePresetName");
verify(mNativeInterface, times(1))
- .groupSetPresetName(eq(0x03), eq(0x01), eq("ExamplePresetName"));
+ .groupSetPresetName(eq(test_group), eq(0x01), eq("ExamplePresetName"));
}
/**
@@ -607,153 +664,233 @@ public class HapClientTest {
doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService)
.getRemoteUuids(any(BluetoothDevice.class));
- // Verify getting current preset return an invalid value when there is no such device
- // available
- Assert.assertEquals(true, mService.getActivePresetIndex(mDevice));
-
- Intent intent = TestUtils.waitForIntent(TIMEOUT_MS, mIntentQueue.get(mDevice));
- Assert.assertNotNull(intent);
- Assert.assertEquals(BluetoothHapClient.ACTION_HAP_ON_ACTIVE_PRESET, intent.getAction());
- Assert.assertEquals(mDevice, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE));
- Assert.assertEquals(BluetoothHapClient.PRESET_INDEX_UNAVAILABLE,
- intent.getIntExtra(BluetoothHapClient.EXTRA_HAP_PRESET_INDEX, -1));
-
mNativeInterface.onDeviceAvailable(getByteAddress(mDevice), 0x03);
- intent = TestUtils.waitForIntent(TIMEOUT_MS, mIntentQueue.get(mDevice));
+ Intent intent = TestUtils.waitForIntent(TIMEOUT_MS, mIntentQueue.get(mDevice));
Assert.assertNotNull(intent);
Assert.assertEquals(BluetoothHapClient.ACTION_HAP_DEVICE_AVAILABLE, intent.getAction());
Assert.assertEquals(mDevice, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE));
Assert.assertEquals(0x03,
- intent.getIntExtra(BluetoothHapClient.EXTRA_HAP_FEATURES, 0x03));
+ intent.getIntExtra(BluetoothHapClient.EXTRA_HAP_FEATURES, 0x00));
}
/**
- * Test that native callback generates proper intent.
+ * Test that native callback generates proper callback call.
*/
@Test
- public void testStackEventOnActivePresetSelected() {
+ public void testStackEventOnFeaturesUpdate() {
+ doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService)
+ .getRemoteUuids(any(BluetoothDevice.class));
+
+ mNativeInterface.onDeviceAvailable(getByteAddress(mDevice), 0x00);
+ mNativeInterface.onFeaturesUpdate(getByteAddress(mDevice), 0x03);
+
+ try {
+ verify(mCallback, after(TIMEOUT_MS).times(1)).onHapFeaturesAvailable(eq(mDevice),
+ eq(0x03));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Test that native callback generates proper callback call.
+ */
+ @Test
+ public void testStackEventOnActivePresetChanged() {
doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService)
.getRemoteUuids(any(BluetoothDevice.class));
mNativeInterface.onActivePresetSelected(getByteAddress(mDevice), 0x01);
- Intent intent = TestUtils.waitForIntent(TIMEOUT_MS, mIntentQueue.get(mDevice));
- Assert.assertNotNull(intent);
- Assert.assertEquals(BluetoothHapClient.ACTION_HAP_ON_ACTIVE_PRESET, intent.getAction());
- Assert.assertEquals(mDevice, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE));
- Assert.assertEquals(0x01,
- intent.getIntExtra(BluetoothHapClient.EXTRA_HAP_PRESET_INDEX, -1));
+ try {
+ verify(mCallback, after(TIMEOUT_MS).times(1)).onActivePresetChanged(eq(mDevice),
+ eq(0x01));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
// Verify that getting current preset returns a proper value now
- Assert.assertEquals(true, mService.getActivePresetIndex(mDevice));
-
- intent = TestUtils.waitForIntent(TIMEOUT_MS, mIntentQueue.get(mDevice));
- Assert.assertNotNull(intent);
- Assert.assertEquals(BluetoothHapClient.ACTION_HAP_ON_ACTIVE_PRESET, intent.getAction());
- Assert.assertEquals(mDevice, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE));
- Assert.assertEquals(0x01,
- intent.getIntExtra(BluetoothHapClient.EXTRA_HAP_PRESET_INDEX, -1));
+ Assert.assertEquals(0x01, mService.getActivePresetIndex(mDevice));
}
/**
- * Test that native callback generates proper intent.
+ * Test that native callback generates proper callback call.
*/
@Test
- public void testStackEventOnCurrentPresetSelectError() {
+ public void testStackEventOnActivePresetSelectError() {
doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService)
.getRemoteUuids(any(BluetoothDevice.class));
- mNativeInterface.onActivePresetSelectError(getByteAddress(mDevice),
- BluetoothHapClient.STATUS_INVALID_PRESET_INDEX);
+ /* Send INVALID_PRESET_INDEX error */
+ mNativeInterface.onActivePresetSelectError(getByteAddress(mDevice), 0x05);
- Intent intent = TestUtils.waitForIntent(TIMEOUT_MS, mIntentQueue.get(mDevice));
- Assert.assertNotNull(intent);
- Assert.assertEquals(BluetoothHapClient.ACTION_HAP_ON_ACTIVE_PRESET_SELECT_ERROR,
- intent.getAction());
- Assert.assertEquals(mDevice, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE));
- Assert.assertEquals(BluetoothHapClient.STATUS_INVALID_PRESET_INDEX,
- intent.getIntExtra(BluetoothHapClient.EXTRA_HAP_STATUS_CODE, -1));
+ try {
+ verify(mCallback, after(TIMEOUT_MS).times(1)).onSelectActivePresetFailed(eq(mDevice),
+ eq(BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
/**
- * Test that native callback generates proper intent.
+ * Test that native callback generates proper callback call.
*/
@Test
public void testStackEventOnPresetInfo() {
doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService)
.getRemoteUuids(any(BluetoothDevice.class));
- int info_reason = BluetoothHapClient.PRESET_INFO_REASON_PRESET_INFO_UPDATE;
+ // Connect and inject initial presets
+ testConnectingDevice(mDevice);
+
+ int info_reason = HapClientStackEvent.PRESET_INFO_REASON_PRESET_INFO_UPDATE;
BluetoothHapPresetInfo[] info =
{new BluetoothHapPresetInfo.Builder()
.setIndex(0x01)
- .setName("PresetName")
+ .setName("OneChangedToUnavailable")
.setWritable(true)
- .setAvailable(true)
+ .setAvailable(false)
.build()};
mNativeInterface.onPresetInfo(getByteAddress(mDevice), info_reason, info);
- Intent intent = TestUtils.waitForIntent(TIMEOUT_MS, mIntentQueue.get(mDevice));
- Assert.assertNotNull(intent);
- Assert.assertEquals(BluetoothHapClient.ACTION_HAP_ON_PRESET_INFO, intent.getAction());
- Assert.assertEquals(mDevice, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE));
- Assert.assertEquals(info_reason,
- intent.getIntExtra(BluetoothHapClient.EXTRA_HAP_PRESET_INFO_REASON, -1));
+ ArgumentCaptor<List<BluetoothHapPresetInfo>> presetsCaptor =
+ ArgumentCaptor.forClass(List.class);
+ try {
+ verify(mCallback, after(TIMEOUT_MS).times(1)).onPresetInfoChanged(eq(mDevice),
+ presetsCaptor.capture(), eq(BluetoothStatusCodes.REASON_REMOTE_REQUEST));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
- ArrayList presets =
- intent.getParcelableArrayListExtra(BluetoothHapClient.EXTRA_HAP_PRESET_INFO);
- Assert.assertNotNull(presets);
+ List<BluetoothHapPresetInfo> presets = presetsCaptor.getValue();
+ Assert.assertEquals(3, presets.size());
- BluetoothHapPresetInfo preset = (BluetoothHapPresetInfo) presets.get(0);
- Assert.assertEquals(preset.getIndex(), info[0].getIndex());
- Assert.assertEquals(preset.getName(), info[0].getName());
- Assert.assertEquals(preset.isWritable(), info[0].isWritable());
- Assert.assertEquals(preset.isAvailable(), info[0].isAvailable());
+ Optional<BluetoothHapPresetInfo> preset = presetsCaptor.getValue()
+ .stream()
+ .filter(p -> 0x01 == p.getIndex())
+ .findFirst();
+ Assert.assertEquals("OneChangedToUnavailable", preset.get().getName());
+ Assert.assertFalse(preset.get().isAvailable());
+ Assert.assertTrue(preset.get().isWritable());
}
/**
- * Test that native callback generates proper intent.
+ * Test that native callback generates proper callback call.
*/
@Test
public void testStackEventOnPresetNameSetError() {
doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService)
.getRemoteUuids(any(BluetoothDevice.class));
+ /* Not a valid name length */
mNativeInterface.onPresetNameSetError(getByteAddress(mDevice), 0x01,
- BluetoothHapClient.STATUS_SET_NAME_NOT_ALLOWED);
+ HapClientStackEvent.STATUS_INVALID_PRESET_NAME_LENGTH);
+ try {
+ verify(mCallback, after(TIMEOUT_MS).times(1)).onSetPresetNameFailed(eq(mDevice),
+ eq(BluetoothStatusCodes.ERROR_HAP_PRESET_NAME_TOO_LONG));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
- Intent intent = TestUtils.waitForIntent(TIMEOUT_MS, mIntentQueue.get(mDevice));
- Assert.assertNotNull(intent);
- Assert.assertEquals(BluetoothHapClient.ACTION_HAP_ON_PRESET_NAME_SET_ERROR,
- intent.getAction());
- Assert.assertEquals(0x01,
- intent.getIntExtra(BluetoothHapClient.EXTRA_HAP_PRESET_INDEX, -1));
- Assert.assertEquals(mDevice, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE));
- Assert.assertEquals(BluetoothHapClient.STATUS_SET_NAME_NOT_ALLOWED,
- intent.getIntExtra(BluetoothHapClient.EXTRA_HAP_STATUS_CODE, -1));
+ /* Invalid preset index provided */
+ mNativeInterface.onPresetNameSetError(getByteAddress(mDevice), 0x01,
+ HapClientStackEvent.STATUS_INVALID_PRESET_INDEX);
+ try {
+ verify(mCallback, after(TIMEOUT_MS).times(1)).onSetPresetNameFailed(eq(mDevice),
+ eq(BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
+ /* Not allowed on this particular preset */
+ mNativeInterface.onPresetNameSetError(getByteAddress(mDevice), 0x01,
+ HapClientStackEvent.STATUS_SET_NAME_NOT_ALLOWED);
+ try {
+ verify(mCallback, after(TIMEOUT_MS).times(1)).onSetPresetNameFailed(eq(mDevice),
+ eq(BluetoothStatusCodes.ERROR_REMOTE_OPERATION_REJECTED));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
+ /* Not allowed on this particular preset at this time, might be possible later on */
+ mNativeInterface.onPresetNameSetError(getByteAddress(mDevice), 0x01,
+ HapClientStackEvent.STATUS_OPERATION_NOT_POSSIBLE);
+ try {
+ verify(mCallback, after(TIMEOUT_MS).times(2)).onSetPresetNameFailed(eq(mDevice),
+ eq(BluetoothStatusCodes.ERROR_REMOTE_OPERATION_REJECTED));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
+ /* Not allowed on all presets - for example missing characteristic */
+ mNativeInterface.onPresetNameSetError(getByteAddress(mDevice), 0x01,
+ HapClientStackEvent.STATUS_OPERATION_NOT_SUPPORTED);
+ try {
+ verify(mCallback, after(TIMEOUT_MS).times(1)).onSetPresetNameFailed(eq(mDevice),
+ eq(BluetoothStatusCodes.ERROR_REMOTE_OPERATION_NOT_SUPPORTED));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
/**
- * Test that native callback generates proper intent.
+ * Test that native callback generates proper callback call.
*/
@Test
- public void testStackEventOnPresetInfoError() {
+ public void testStackEventOnGroupPresetNameSetError() {
doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService)
.getRemoteUuids(any(BluetoothDevice.class));
- mNativeInterface.onPresetInfoError(getByteAddress(mDevice), 0x01,
- BluetoothHapClient.STATUS_INVALID_PRESET_INDEX);
+ /* Not a valid name length */
+ mNativeInterface.onGroupPresetNameSetError(0x01, 0x01,
+ HapClientStackEvent.STATUS_INVALID_PRESET_NAME_LENGTH);
+ try {
+ verify(mCallback, after(TIMEOUT_MS).times(1)).onSetPresetNameForGroupFailed(0x01,
+ BluetoothStatusCodes.ERROR_HAP_PRESET_NAME_TOO_LONG);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
- Intent intent = TestUtils.waitForIntent(TIMEOUT_MS, mIntentQueue.get(mDevice));
- Assert.assertNotNull(intent);
- Assert.assertEquals(BluetoothHapClient.ACTION_HAP_ON_PRESET_INFO_GET_ERROR,
- intent.getAction());
- Assert.assertEquals(0x01,
- intent.getIntExtra(BluetoothHapClient.EXTRA_HAP_PRESET_INDEX, -1));
- Assert.assertEquals(mDevice, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE));
- Assert.assertEquals(BluetoothHapClient.STATUS_INVALID_PRESET_INDEX,
- intent.getIntExtra(BluetoothHapClient.EXTRA_HAP_STATUS_CODE, -1));
+ /* Invalid preset index provided */
+ mNativeInterface.onGroupPresetNameSetError(0x01, 0x01,
+ HapClientStackEvent.STATUS_INVALID_PRESET_INDEX);
+ try {
+ verify(mCallback, after(TIMEOUT_MS).times(1)).onSetPresetNameForGroupFailed(0x01,
+ BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
+ /* Not allowed on this particular preset */
+ mNativeInterface.onGroupPresetNameSetError(0x01, 0x01,
+ HapClientStackEvent.STATUS_SET_NAME_NOT_ALLOWED);
+ try {
+ verify(mCallback, after(TIMEOUT_MS).times(1)).onSetPresetNameForGroupFailed(0x01,
+ BluetoothStatusCodes.ERROR_REMOTE_OPERATION_REJECTED);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
+ /* Not allowed on this particular preset at this time, might be possible later on */
+ mNativeInterface.onGroupPresetNameSetError(0x01, 0x01,
+ HapClientStackEvent.STATUS_OPERATION_NOT_POSSIBLE);
+ try {
+ verify(mCallback, after(TIMEOUT_MS).times(2)).onSetPresetNameForGroupFailed(0x01,
+ BluetoothStatusCodes.ERROR_REMOTE_OPERATION_REJECTED);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
+ /* Not allowed on all presets - for example if peer is missing optional CP characteristic */
+ mNativeInterface.onGroupPresetNameSetError(0x01, 0x01,
+ HapClientStackEvent.STATUS_OPERATION_NOT_SUPPORTED);
+ try {
+ verify(mCallback, after(TIMEOUT_MS).times(1)).onSetPresetNameForGroupFailed(0x01,
+ BluetoothStatusCodes.ERROR_REMOTE_OPERATION_NOT_SUPPORTED);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
/**
@@ -812,21 +949,57 @@ public class HapClientTest {
Assert.assertEquals(device, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE));
Assert.assertEquals(evt.valueInt1,
intent.getIntExtra(BluetoothHapClient.EXTRA_HAP_FEATURES, -1));
+
+ evt = new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_DEVICE_FEATURES);
+ evt.device = device;
+ evt.valueInt1 = 0x01; // features
+ mService.messageFromNative(evt);
+
+ try {
+ verify(mCallback, after(TIMEOUT_MS).times(1)).onHapFeaturesAvailable(eq(device),
+ eq(evt.valueInt1));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
+ // Inject some initial presets
+ List<BluetoothHapPresetInfo> presets =
+ new ArrayList<BluetoothHapPresetInfo>(Arrays.asList(
+ new BluetoothHapPresetInfo.Builder()
+ .setIndex(0x01)
+ .setName("One")
+ .setAvailable(true)
+ .setWritable(false)
+ .build(),
+ new BluetoothHapPresetInfo.Builder()
+ .setIndex(0x02)
+ .setName("Two")
+ .setAvailable(true)
+ .setWritable(true)
+ .build(),
+ new BluetoothHapPresetInfo.Builder()
+ .setIndex(0x03)
+ .setName("Three")
+ .setAvailable(false)
+ .setWritable(false)
+ .build()));
+ mService.updateDevicePresetsCache(device,
+ HapClientStackEvent.PRESET_INFO_REASON_ALL_PRESET_INFO, presets);
}
- private void testOnActivePresetSelected(BluetoothDevice device, int index) {
+ private void testOnActivePresetChanged(BluetoothDevice device, int index) {
HapClientStackEvent evt =
new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED);
evt.device = device;
evt.valueInt1 = index;
mService.messageFromNative(evt);
- Intent intent = TestUtils.waitForIntent(TIMEOUT_MS, mIntentQueue.get(device));
- Assert.assertNotNull(intent);
- Assert.assertEquals(BluetoothHapClient.ACTION_HAP_ON_ACTIVE_PRESET, intent.getAction());
- Assert.assertEquals(device, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE));
- Assert.assertEquals(index,
- intent.getIntExtra(BluetoothHapClient.EXTRA_HAP_PRESET_INDEX, -1));
+ try {
+ verify(mCallback, after(TIMEOUT_MS).times(1)).onActivePresetChanged(eq(device),
+ eq(evt.valueInt1));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
/**
diff --git a/android/app/tests/unit/src/com/android/bluetooth/mcp/McpServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/mcp/McpServiceTest.java
index 5bb690ddb6..b467f04fd2 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/mcp/McpServiceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/mcp/McpServiceTest.java
@@ -50,11 +50,15 @@ public class McpServiceTest {
private McpService mMcpService;
private Context mTargetContext;
- @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule();
+ @Rule
+ public final ServiceTestRule mServiceRule = new ServiceTestRule();
- @Mock private AdapterService mAdapterService;
- @Mock private MediaControlGattService mMockMcpService;
- @Mock private MediaControlProfile mMediaControlProfile;
+ @Mock
+ private AdapterService mAdapterService;
+ @Mock
+ private MediaControlGattService mMockMcpService;
+ @Mock
+ private MediaControlProfile mMediaControlProfile;
@Before
public void setUp() throws Exception {
@@ -115,4 +119,23 @@ public class McpServiceTest {
Assert.assertEquals(BluetoothDevice.ACCESS_REJECTED,
mMcpService.getDeviceAuthorization(device1));
}
+
+ @Test
+ public void testStopMcpService() {
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+ public void run() {
+ Assert.assertTrue(mMcpService.stop());
+ }
+ });
+ Assert.assertNull(McpService.getMcpService());
+ Assert.assertNull(McpService.getMediaControlProfile());
+
+ McpService.setMediaControlProfileForTesting(mMediaControlProfile);
+ // Try to restart the service. Note: must be done on the main thread
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+ public void run() {
+ Assert.assertTrue(mMcpService.start());
+ }
+ });
+ }
}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/tbs/TbsGenericTest.java b/android/app/tests/unit/src/com/android/bluetooth/tbs/TbsGenericTest.java
index 4a79b3904a..eae7e099f2 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/tbs/TbsGenericTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/tbs/TbsGenericTest.java
@@ -31,6 +31,7 @@ import androidx.test.InstrumentationRegistry;
import androidx.test.filters.MediumTest;
import androidx.test.rule.ServiceTestRule;
import androidx.test.runner.AndroidJUnit4;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import com.android.bluetooth.TestUtils;
import com.android.bluetooth.btservice.AdapterService;
@@ -71,12 +72,14 @@ public class TbsGenericTest {
private @Captor ArgumentCaptor<Integer> mDefaultGtbsTechnologyCaptor;
private @Captor ArgumentCaptor<TbsGatt.Callback> mTbsGattCallback;
+ private static Context mContext;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mAdapter = BluetoothAdapter.getDefaultAdapter();
+ mContext = getInstrumentation().getTargetContext();
// Default TbsGatt mock behavior
doReturn(true).when(mTbsGatt).init(mGtbsCcidCaptor.capture(), mGtbsUciCaptor.capture(),
@@ -97,6 +100,7 @@ public class TbsGenericTest {
doReturn(true).when(mTbsGatt).clearIncomingCall();
doReturn(true).when(mTbsGatt).setCallFriendlyName(anyInt(), anyString());
doReturn(true).when(mTbsGatt).clearFriendlyName();
+ doReturn(mContext).when(mTbsGatt).getContext();
mTbsGeneric = new TbsGeneric();
mTbsGeneric.init(mTbsGatt);
diff --git a/android/blueberry/OWNERS b/android/blueberry/OWNERS
new file mode 100644
index 0000000000..610b34604a
--- /dev/null
+++ b/android/blueberry/OWNERS
@@ -0,0 +1,5 @@
+# Project owners
+girardier@google.com
+licorne@google.com
+uael@google.com
+charliebout@google.com
diff --git a/android/blueberry/server/Android.bp b/android/blueberry/server/Android.bp
new file mode 100644
index 0000000000..705ffa6c7e
--- /dev/null
+++ b/android/blueberry/server/Android.bp
@@ -0,0 +1,25 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test {
+ name: "BlueberryServer",
+ srcs: ["src/**/*.kt"],
+ certificate: "platform",
+
+ static_libs: [
+ "androidx.test.runner",
+ "androidx.test.core",
+ "grpc-java-netty-shaded-test",
+ "grpc-java-lite",
+ "guava",
+ "opencensus-java-api",
+ ],
+
+ dex_preopt: {
+ enabled: false,
+ },
+ optimize: {
+ enabled: false,
+ },
+}
diff --git a/android/blueberry/server/AndroidManifest.xml b/android/blueberry/server/AndroidManifest.xml
new file mode 100644
index 0000000000..16a47bfc83
--- /dev/null
+++ b/android/blueberry/server/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.blueberry">
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <uses-permission android:name="android.permission.INTERNET" />
+
+ <instrumentation android:name="com.android.blueberry.Server"
+ android:targetPackage="com.android.blueberry"
+ android:label="Blueberry Android Server" />
+</manifest>
diff --git a/android/blueberry/server/README.md b/android/blueberry/server/README.md
new file mode 100644
index 0000000000..ebeea949a1
--- /dev/null
+++ b/android/blueberry/server/README.md
@@ -0,0 +1,117 @@
+# Blueberry Android server
+
+The Blueberry Android server exposes the [Blueberry test interfaces](
+go/blueberry-doc) over gRPC implemented on top of the Android Bluetooth SDK.
+
+## Getting started
+
+Using Blueberry Android server requires to:
+
+* Build AOSP for your DUT, which can be either a physical device or an Android
+ Virtual Device (AVD).
+* [Only for virtual tests] Build Rootcanal, the Android
+ virtual Bluetooth Controller.
+* Setup your test environment.
+* Build, install, and run Blueberry server.
+* Run your tests.
+
+### 1. Build and run AOSP code
+
+Refer to the AOSP documentation to [initialize and sync](
+https://g3doc.corp.google.com/company/teams/android/developing/init-sync.md)
+AOSP code, and [build](
+https://g3doc.corp.google.com/company/teams/android/developing/build-flash.md)
+it for your DUT (`aosp_cf_x86_64_phone-userdebug` for the emulator).
+
+**If your DUT is a physical device**, flash the built image on it. You may
+need to use [Remote Device Proxy](
+https://g3doc.corp.google.com/company/teams/android/wfh/adb/remote_device_proxy.md)
+if you are using a remote instance to build. If you are also using `adb` on
+your local machine, you may need to force kill the local `adb` server (`adb
+kill-server` before using Remote Device Proxy.
+
+**If your DUT is a Cuttlefish virtual device**, then proceed with the following steps:
+
+* Connect to your [Chrome Remote Desktop](
+ https://remotedesktop.corp.google.com/access/).
+* Create a local Cuttlefish instance using your locally built image with the command
+ `acloud create --local-instance --local-image` (see [documentation](
+ go/acloud-manual#local-instance-using-a-locally-built-image))
+
+### 2. Build Rootcanal [only for virtual tests on a physical device]
+
+Rootcanal is a virtual Bluetooth Controller that allows emulating Bluetooth
+communications. It is used by default within Cuttlefish when running it using the [acloud](go/acloud) command (and thus this step is not
+needed) and is required for all virtual tests. However, it does not come
+preinstalled on a build for a physical device.
+
+Proceed with the [following instructions](
+https://docs.google.com/document/d/1-qoK1HtdOKK6sTIKAToFf7nu9ybxs8FQWU09idZijyc/edit#heading=h.x9snb54sjlu9)
+to build and install Rootcanal on your DUT.
+
+### 3. Setup your test environment
+
+Each time when starting a new ADB server to communicate with your DUT, proceed
+with the following steps to setup the test environment:
+
+* If running virtual tests (such as PTS-bot) on a physical device:
+ * Run Rootcanal:
+ `adb root` then
+ `adb shell ./vendor/bin/hw/android.hardware.bluetooth@1.1-service.sim &`
+ * Forward Rootcanal port through ADB:
+ `adb forward tcp:<rootcanal-port> tcp:<rootcanal-port>`.
+ Rootcanal port number may differ depending on its configuration. It is
+ 7200 for the AVD, and generally 6211 for physical devices.
+* Forward Blueberry Android server port through ADB:
+ `adb forward tcp:8999 tcp:8999`.
+
+The above steps can be done by executing the `setup.sh` helper script (the
+`-rootcanal` option must be used for virtual tests on a physical device).
+
+Finally, you must also make sure that the machine on which tests are executed
+can access the ports of the Blueberry Android server, Rootcanal (if required),
+and ADB (if required).
+
+You can also check the usage examples provided below.
+
+### 4. Build, install, and run Blueberry Android server
+
+* `m BlueberryServer`
+* `adb install -r -g out/target/product/<device>/testcases/Blueberry/arm64/Blueberry.apk`
+
+* Start the instrumented app:
+* `adb shell am instrument -w -e Debug false com.android.blueberry/.Server`
+
+### 5. Run your tests
+
+You should now be fully set up to run your tests!
+
+### Usage examples
+
+Here are some usage examples:
+
+* **DUT**: physical
+ **Test type**: virtual
+ **Test executer**: remote instance (for instance a Cloudtop) accessed via SSH
+ **Blueberry Android server repository location**: local machine (typically
+ using Android Studio)
+
+ * On your local machine: `./setup.sh --rootcanal`.
+ * On your local machine: build and install the app on your DUT.
+ * Log on your remote instance, and forward Rootcanal port (6211, may change
+ depending on your build) and Blueberry Android server (8999) port:
+ `ssh -R 6211:localhost:6211 -R 8999:localhost:8999 <remote-instance>`.
+ Optionnally, you can also share ADB port to your remote instance (if
+ needed) by adding `-R 5037:localhost:5037` to the command.
+ * On your remote instance: execute your tests.
+
+* **DUT**: virtual (running in remote instance)
+ **Test type**: virtual
+ **Test executer**: remote instance
+ **Blueberry Android server repository location**: remote instance
+
+ On your remote instance:
+ * `./setup.sh`.
+ * Build and install the app on the AVD.
+ * Execute your tests.
+
diff --git a/android/blueberry/server/scripts/setup.sh b/android/blueberry/server/scripts/setup.sh
new file mode 100755
index 0000000000..1ade4f5159
--- /dev/null
+++ b/android/blueberry/server/scripts/setup.sh
@@ -0,0 +1,12 @@
+#!/bin/env bash
+
+# Run Rootcanal and forward port
+if [ "$1" == "--rootcanal" ]
+then
+ adb root
+ adb shell ./vendor/bin/hw/android.hardware.bluetooth@1.1-service.sim &
+ adb forward tcp:6211 tcp:6211
+fi
+
+# Forward Blueberry server port
+adb forward tcp:8999 tcp:8999
diff --git a/android/blueberry/server/src/com/android/blueberry/Server.kt b/android/blueberry/server/src/com/android/blueberry/Server.kt
new file mode 100644
index 0000000000..cbfff9084d
--- /dev/null
+++ b/android/blueberry/server/src/com/android/blueberry/Server.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 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 com.android.blueberry
+
+import android.os.Bundle
+import android.os.Debug
+import android.util.Log
+import androidx.test.runner.MonitoringInstrumentation
+import io.grpc.netty.shaded.io.grpc.netty.NettyServerBuilder
+
+class Server : MonitoringInstrumentation() {
+
+ private val TAG = "BlueberryServer"
+ private val GRPC_PORT = 8999
+
+ override fun onCreate(arguments: Bundle) {
+ super.onCreate(arguments)
+
+ // Activate debugger
+ if (arguments.getString("debug").toBoolean()) {
+ Log.i(TAG, "Waiting for debugger to connect...")
+ Debug.waitForDebugger()
+ Log.i(TAG, "Debugger connected")
+ }
+
+ // Start instrumentation thread
+ start()
+ }
+
+ override fun onStart() {
+ super.onStart()
+
+ NettyServerBuilder.forPort(GRPC_PORT).build().start()
+ Log.d(TAG, "Blueberry Server started at $GRPC_PORT")
+ }
+}
diff --git a/build.py b/build.py
index 4bc51486b8..2bffdc3182 100755
--- a/build.py
+++ b/build.py
@@ -59,13 +59,14 @@ USE_DEFAULTS = {
}
VALID_TARGETS = [
+ 'all', # All targets except test and clean
+ 'clean', # Clean up output directory
+ 'docs', # Build Rust docs
+ 'main', # Build the main C++ codebase
'prepare', # Prepare the output directory (gn gen + rust setup)
- 'tools', # Build the host tools (i.e. packetgen)
'rust', # Build only the rust components + copy artifacts to output dir
- 'main', # Build the main C++ codebase
'test', # Run the unit tests
- 'clean', # Clean up output directory
- 'all', # All targets except test and clean
+ 'tools', # Build the host tools (i.e. packetgen)
]
# TODO(b/190750167) - Host tests are disabled until we are full bazel build
@@ -98,19 +99,24 @@ REQUIRED_APT_PACKAGES = [
'generate-ninja',
'gnupg',
'gperf',
+ 'libc++abi-dev',
'libc++-dev',
'libdbus-1-dev',
+ 'libdouble-conversion-dev',
'libevent-dev',
'libevent-dev',
'libflatbuffers-dev',
'libflatbuffers1',
'libgl1-mesa-dev',
'libglib2.0-dev',
+ 'libgtest-dev',
+ 'libgmock-dev',
'liblz4-tool',
'libncurses5',
'libnss3-dev',
'libprotobuf-dev',
'libre2-9',
+ 'libre2-dev',
'libssl-dev',
'libtinyxml2-dev',
'libx11-dev',
@@ -327,7 +333,7 @@ class HostBuild():
'libbase_ver': self._get_basever(),
'enable_exceptions': os.environ.get('CXXEXCEPTIONS', 0) == '1',
'external_cflags': [],
- 'external_cxxflags': [],
+ 'external_cxxflags': ["-DNDEBUG"],
'enable_werror': False,
}
@@ -413,6 +419,10 @@ class HostBuild():
shutil.copy(
os.path.join(self._gn_default_output(), 'bluetooth_packetgen'), os.path.join(self.env['CARGO_HOME'], 'bin'))
+ def _target_docs(self):
+ """Build the Rust docs."""
+ self.run_command('docs', ['cargo', 'doc'], cwd=os.path.join(self.platform_dir, 'bt'), env=self.env)
+
def _target_rust(self):
""" Build rust artifacts in an already prepared environment.
"""
@@ -427,7 +437,11 @@ class HostBuild():
""" Runs the host tests.
"""
# Rust tests first
- self.run_command('test', ['cargo', 'test'], cwd=os.path.join(self.platform_dir, 'bt'), env=self.env)
+ rust_test_cmd = ['cargo', 'test']
+ if self.args.test_name:
+ rust_test_cmd = rust_test_cmd + [self.args.test_name]
+
+ self.run_command('test', rust_test_cmd, cwd=os.path.join(self.platform_dir, 'bt'), env=self.env)
# Host tests second based on host test list
for t in HOST_TESTS:
@@ -502,7 +516,7 @@ class HostBuild():
pass
def _target_all(self):
- """ Build all common targets (skipping test and clean).
+ """ Build all common targets (skipping doc, test, and clean).
"""
self._target_prepare()
self._target_tools()
@@ -514,12 +528,19 @@ class HostBuild():
"""
print('Building target ', self.target)
+ # Validate that the target is valid
+ if self.target not in VALID_TARGETS:
+ print('Target {} is not valid. Must be in {}', self.target, VALID_TARGETS)
+ return
+
if self.target == 'prepare':
self._target_prepare()
elif self.target == 'tools':
self._target_tools()
elif self.target == 'rust':
self._target_rust()
+ elif self.target == 'docs':
+ self._target_docs()
elif self.target == 'main':
self._target_main()
elif self.target == 'test':
@@ -594,7 +615,10 @@ class Bootstrap():
# Create symlinks
for pairs in symlinks:
(src, dst) = pairs
- os.unlink(dst)
+ try:
+ os.unlink(dst)
+ except Exception as e:
+ print(e)
os.symlink(src, dst)
# Write to setup complete file so we don't repeat this step
@@ -759,7 +783,8 @@ if __name__ == '__main__':
parser.add_argument(
'--no-strip', help='Skip stripping binaries during install.', default=False, action='store_true')
parser.add_argument('--use', help='Set a specific use flag.')
- parser.add_argument('--notest', help="Don't compile test code.", default=False, action='store_true')
+ parser.add_argument('--notest', help='Don\'t compile test code.', default=False, action='store_true')
+ parser.add_argument('--test-name', help='Run test with this string in the name.', default=None)
parser.add_argument('--target', help='Run specific build target')
parser.add_argument('--sysroot', help='Set a specific sysroot path', default='/')
parser.add_argument('--libdir', help='Libdir - default = usr/lib', default='usr/lib')
diff --git a/floss/OWNERS b/floss/OWNERS
new file mode 100644
index 0000000000..45bfdd2be4
--- /dev/null
+++ b/floss/OWNERS
@@ -0,0 +1 @@
+include platform/packages/modules/Bluetooth:/OWNERS_chromeos
diff --git a/floss/build/Dockerfile b/floss/build/Dockerfile
new file mode 100644
index 0000000000..7e938f9a10
--- /dev/null
+++ b/floss/build/Dockerfile
@@ -0,0 +1,76 @@
+# Build environment for Floss
+#
+# This dockerfile generates the build environment required to build Floss, which
+# is the Linux build for the Fluoride Bluetooth stack.
+
+# Inherit from a recent Debian version. The slim version is a smaller variant
+# meant for containers.
+FROM debian:bookworm-slim
+
+# First install all required apt packages.
+RUN apt-get update && \
+ apt-get install -y \
+ bison \
+ build-essential \
+ clang \
+ cmake \
+ curl \
+ debmake \
+ flatbuffers-compiler \
+ flex \
+ g++-multilib \
+ gcc-multilib \
+ generate-ninja \
+ gnupg \
+ gperf \
+ libabsl-dev \
+ libc++abi-dev \
+ libc++-dev \
+ libdbus-1-dev \
+ libdouble-conversion-dev \
+ libevent-dev \
+ libflatbuffers-dev \
+ libflatbuffers1 \
+ libgl1-mesa-dev \
+ libglib2.0-dev \
+ libgtest-dev \
+ libgmock-dev \
+ liblz4-tool \
+ libncurses5 \
+ libnss3-dev \
+ libprotobuf-dev \
+ libre2-9 \
+ libre2-dev \
+ libssl-dev \
+ libtinyxml2-dev \
+ libx11-dev \
+ libxml2-utils \
+ ninja-build \
+ openssl \
+ protobuf-compiler \
+ python3 \
+ unzip \
+ x11proto-core-dev \
+ xsltproc \
+ zip \
+ zlib1g-dev \
+ ;
+
+# Next install the Rust toolchain.
+RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
+
+# Add .cargo/bin to $PATH
+ENV PATH="/root/.cargo/bin:${PATH}"
+
+# Install cargo packages required on build image.
+RUN cargo install cxxbridge-cmd --version 1.0.42
+
+# Rename llvm packages. By default, they are named 11vm-ar-13, etc. which won't
+# work properly with the build.
+ADD llvm-rename.sh /tmp
+RUN /tmp/llvm-rename.sh 13
+
+# At this point, the base container is ready. Now we need to build and install
+# both libchrome and modp-b64. If you ran this via `docker-build-image.py`, this
+# will be done after the image is created and tagged. Otherwise, you need to
+# manually mount the source and run the dpkg builders in `system/build/dpkg`.
diff --git a/floss/build/README.md b/floss/build/README.md
new file mode 100644
index 0000000000..ac58410fb1
--- /dev/null
+++ b/floss/build/README.md
@@ -0,0 +1,23 @@
+# Docker build for Floss
+
+This repo contains the Docker image build rule, used to generate the docker
+image necessary to build Floss. If building a new docker image, run
+`docker-build-image.py` with the tag `floss:latest`.
+
+## Using the docker image to build
+
+Once the Docker image is built (and assuming it's tagged as `floss:latest`), you
+should use the `build-in-docker.py` script to build the current repo.
+
+This script will use the local `floss:latest` (or pull it from the registry),
+mount (or create) the `floss-out` volume to `/root/.floss` and the current
+source to `/root/src` before running these commands in the container:
+
+* `cd /root/src`
+* `./build.py --run-bootstrap`
+* `./build.py --libdir=/usr/lib/x86-64_linux_gnu/`
+
+If you want to run the build more quickly (or pass other commands), run
+`build-in-docker.py --only-start`. This will only start the container for you
+(doing the correct mounts) and will print the commands it would have run via
+docker exec normally.
diff --git a/floss/build/build-in-docker.py b/floss/build/build-in-docker.py
new file mode 100755
index 0000000000..a84d2dd7c9
--- /dev/null
+++ b/floss/build/build-in-docker.py
@@ -0,0 +1,163 @@
+#!/usr/bin/env python3
+
+import argparse
+import os
+import subprocess
+import sys
+
+
+class FlossDockerRunner:
+ """Runs Floss build inside docker container."""
+
+ # Commands to run for build
+ BUILD_COMMANDS = [
+ # First run bootstrap to get latest code + create symlinks
+ ['/root/src/build.py', '--run-bootstrap'],
+
+ # Clean up any previous artifacts inside the volume
+ ['/root/src/build.py', '--target', 'clean'],
+
+ # Run normal code builder
+ ['/root/src/build.py', '--target', 'all'],
+
+ # Run tests
+ ['/root/src/build.py', '--target', 'test'],
+ ]
+
+ def __init__(self, workdir, rootdir, image_tag, volume_tag):
+ """ Constructor.
+
+ Args:
+ workdir: Current working directory (should be the script path).
+ rootdir: Root directory for Bluetooth.
+ build_tag: Tag for docker image used for building.
+ """
+ self.workdir = workdir
+ self.rootdir = rootdir
+ self.image_tag = image_tag
+ self.env = os.environ.copy()
+
+ # Name of running container
+ self.container_name = 'floss-docker-runner'
+
+ # Name of volume where we'll send build output
+ self.volume_name = volume_tag
+
+ def run_command(self, target, args, cwd=None, env=None, ignore_rc=False):
+ """ Run command and stream the output.
+ """
+ # Set some defaults
+ if not cwd:
+ cwd = self.workdir
+ if not env:
+ env = self.env
+
+ rc = 0
+ process = subprocess.Popen(args, cwd=cwd, env=env, stdout=subprocess.PIPE)
+ while True:
+ line = process.stdout.readline()
+ print(line.decode('utf-8'), end="")
+ if not line:
+ rc = process.poll()
+ if rc is not None:
+ break
+
+ time.sleep(0.1)
+
+ if rc != 0 and not ignore_rc:
+ raise Exception("{} failed. Return code is {}".format(target, rc))
+
+ def _create_volume_if_needed(self):
+ # Check if the volume exists. Otherwise create it.
+ try:
+ subprocess.check_output(['docker', 'volume', 'inspect', self.volume_name])
+ finally:
+ self.run_command('docker volume create', ['docker', 'volume', 'create', self.volume_name])
+
+ def start_container(self):
+ """Starts the docker container with correct mounts."""
+ # Stop any previously started container.
+ self.stop_container(ignore_error=True)
+
+ # Create volume and create mount string
+ self._create_volume_if_needed()
+ mount_output_volume = 'type=volume,src={},dst=/root/.floss'.format(self.volume_name)
+
+ # Mount the source directory
+ mount_src_dir = 'type=bind,src={},dst=/root/src'.format(self.rootdir)
+
+ # Run the docker image. It will run `tail` indefinitely so the container
+ # doesn't close and we can run `docker exec` on it.
+ self.run_command('docker run', [
+ 'docker', 'run', '--name', self.container_name, '--mount', mount_output_volume, '--mount', mount_src_dir,
+ '-d', self.image_tag, 'tail', '-f', '/dev/null'
+ ])
+
+ def stop_container(self, ignore_error=False):
+ """Stops the docker container for build."""
+ self.run_command('docker stop', ['docker', 'stop', '-t', '1', self.container_name], ignore_rc=ignore_error)
+ self.run_command('docker rm', ['docker', 'rm', self.container_name], ignore_rc=ignore_error)
+
+ def do_build(self):
+ """Runs the basic build commands."""
+ # Start container before building
+ self.start_container()
+
+ # Run all commands
+ for i, cmd in enumerate(self.BUILD_COMMANDS):
+ self.run_command('docker exec #{}'.format(i), ['docker', 'exec', '-it', self.container_name] + cmd)
+
+ # Stop container before exiting
+ self.stop_container()
+
+ def print_do_build(self):
+ """Prints the commands for building."""
+ docker_exec = ['docker', 'exec', '-it', self.container_name]
+ print('Normally, build would run the following commands: \n')
+ for cmd in self.BUILD_COMMANDS:
+ print(' '.join(docker_exec + cmd))
+
+ def check_docker_runnable(self):
+ try:
+ subprocess.check_output(['docker', 'ps'], stderr=subprocess.STDOUT)
+ except subprocess.CalledProcessError as err:
+ if 'denied' in err.output.decode('utf-8'):
+ print('Run script as sudo')
+ else:
+ print('Unexpected error: {}'.format(err.output.decode('utf-8')))
+
+ return False
+
+ # No exception means docker is ok
+ return True
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser('Builder Floss inside docker image.')
+ parser.add_argument(
+ '--only-start',
+ action='store_true',
+ default=False,
+ help='Only start the container. Prints the commands it would have ran.')
+ parser.add_argument('--only-stop', action='store_true', default=False, help='Only stop the container and exit.')
+ parser.add_argument('--image-tag', default='floss:latest', help='Docker image to use to build.')
+ parser.add_argument('--volume-tag', default='floss-out', help='Name of volume to use.')
+ args = parser.parse_args()
+
+ # cwd should be set to same directory as this script (that's where Dockerfile
+ # is kept).
+ workdir = os.path.dirname(os.path.abspath(sys.argv[0]))
+ rootdir = os.path.abspath(os.path.join(workdir, '../..'))
+
+ fdr = FlossDockerRunner(workdir, rootdir, args.image_tag, args.volume_tag)
+
+ # Make sure docker is runnable before continuing
+ if fdr.check_docker_runnable():
+ # Handle some flags
+ if args.only_start:
+ fdr.start_container()
+ fdr.print_do_build()
+ elif args.only_stop:
+ fdr.stop_container()
+ else:
+ fdr.do_build()
diff --git a/floss/build/docker-build-image.py b/floss/build/docker-build-image.py
new file mode 100755
index 0000000000..81b622b87b
--- /dev/null
+++ b/floss/build/docker-build-image.py
@@ -0,0 +1,147 @@
+#!/usr/bin/env python3
+
+import argparse
+import os
+import sys
+import subprocess
+
+SRC_MOUNT = "/root/src"
+
+
+class DockerImageBuilder:
+ """Builds the docker image for Floss build environment."""
+
+ def __init__(self, workdir, rootdir, tag):
+ """ Constructor.
+
+ Args:
+ workdir: Working directory for this script. Dockerfile should exist here.
+ rootdir: Root directory for Bluetooth.
+ tag: Label in format |name:version|.
+ """
+ self.workdir = workdir
+ self.rootdir = rootdir
+ (self.name, self.version) = tag.split(':')
+ self.build_tag = '{}:{}'.format(self.name, 'buildtemp')
+ self.container_name = 'floss-buildtemp'
+ self.final_tag = tag
+ self.env = os.environ.copy()
+
+ # Mark dpkg builders for docker
+ self.env['LIBCHROME_DOCKER'] = '1'
+ self.env['MODP_DOCKER'] = '1'
+
+ def run_command(self, target, args, cwd=None, env=None, ignore_rc=False):
+ """ Run command and stream the output.
+ """
+ # Set some defaults
+ if not cwd:
+ cwd = self.workdir
+ if not env:
+ env = self.env
+
+ rc = 0
+ process = subprocess.Popen(args, cwd=cwd, env=env, stdout=subprocess.PIPE)
+ while True:
+ line = process.stdout.readline()
+ print(line.decode('utf-8'), end="")
+ if not line:
+ rc = process.poll()
+ if rc is not None:
+ break
+
+ time.sleep(0.1)
+
+ if rc != 0 and not ignore_rc:
+ raise Exception("{} failed. Return code is {}".format(target, rc))
+
+ def _docker_build(self):
+ self.run_command('docker build', ['docker', 'build', '-t', self.build_tag, '.'])
+
+ def _build_dpkg_and_commit(self):
+ # Try to remove any previous instance of the container that may be
+ # running if this script didn't complete cleanly last time.
+ self.run_command('docker stop', ['docker', 'stop', '-t', '1', self.container_name], ignore_rc=True)
+ self.run_command('docker rm', ['docker', 'rm', self.container_name], ignore_rc=True)
+
+ # Runs never terminating application on the newly built image in detached mode
+ mount_str = 'type=bind,src={},dst={},readonly'.format(self.rootdir, SRC_MOUNT)
+ self.run_command('docker run', [
+ 'docker', 'run', '--name', self.container_name, '--mount', mount_str, '-d', self.build_tag, 'tail', '-f',
+ '/dev/null'
+ ])
+
+ commands = [
+ # Create the output directories
+ ['mkdir', '-p', '/tmp/libchrome', '/tmp/modpb64'],
+
+ # Run the dpkg builder for modp_b64
+ ['/root/src/system/build/dpkg/modp_b64/gen-src-pkg.sh', '/tmp/modpb64'],
+
+ # Install modp_b64 since libchrome depends on it
+ ['find', '/tmp/modpb64', '-name', 'modp*.deb', '-exec', 'dpkg', '-i', '{}', '+'],
+
+ # Run the dpkg builder for libchrome
+ ['/root/src/system/build/dpkg/libchrome/gen-src-pkg.sh', '/tmp/libchrome'],
+
+ # Install libchrome.
+ ['find', '/tmp/libchrome', '-name', 'libchrome_*.deb', '-exec', 'dpkg', '-i', '{}', '+'],
+
+ # Delete intermediate files
+ ['rm', '-rf', '/tmp/libchrome', '/tmp/modpb64'],
+ ]
+
+ # Run commands in container first to install everything.
+ for i, cmd in enumerate(commands):
+ self.run_command('docker exec #{}'.format(i), ['docker', 'exec', '-it', self.container_name] + cmd)
+
+ # Commit changes into the final tag name
+ self.run_command('docker commit', ['docker', 'commit', self.container_name, self.final_tag])
+
+ # Stop running the container and remove it
+ self.run_command('docker stop', ['docker', 'stop', '-t', '1', self.container_name])
+ self.run_command('docker rm', ['docker', 'rm', self.container_name])
+
+ def _check_docker_runnable(self):
+ try:
+ subprocess.check_output(['docker', 'ps'], stderr=subprocess.STDOUT)
+ except subprocess.CalledProcessError as err:
+ if 'denied' in err.output.decode('utf-8'):
+ print('Run script as sudo')
+ else:
+ print('Unexpected error: {}'.format(err.output.decode('utf-8')))
+
+ return False
+
+ # No exception means docker is ok
+ return True
+
+ def build(self):
+ if not self._check_docker_runnable():
+ return
+
+ # First build the docker image
+ self._docker_build()
+
+ # Then build libchrome and modp-b64 inside the docker image and install
+ # them. Commit those changes to the final label.
+ self._build_dpkg_and_commit()
+
+
+def main():
+ parser = argparse.ArgumentParser(description='Build docker image for Floss build environment.')
+ parser.add_argument('--tag', required=True, help='Tag for docker image. i.e. floss:latest')
+ args = parser.parse_args()
+
+ # cwd should be set to same directory as this script (that's where Dockerfile
+ # is kept).
+ workdir = os.path.dirname(os.path.abspath(sys.argv[0]))
+ rootdir = os.path.abspath(os.path.join(workdir, '../..'))
+
+ # Build the docker image
+ dib = DockerImageBuilder(workdir, rootdir, args.tag)
+ dib.build()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/floss/build/llvm-rename.sh b/floss/build/llvm-rename.sh
new file mode 100755
index 0000000000..454d19bf99
--- /dev/null
+++ b/floss/build/llvm-rename.sh
@@ -0,0 +1,57 @@
+#!/usr/bin/env bash
+
+# Rename all llvm binaries using update-alternatives
+# Without this, the llvm binaries must have the version appended at the end
+# instead of just using the base name
+function rename_llvm_binaries {
+ version=$1
+ priority=100
+
+ update-alternatives \
+ --install /usr/bin/llvm-config llvm-config /usr/bin/llvm-config-${version} ${priority} \
+ --slave /usr/bin/llvm-ar llvm-ar /usr/bin/llvm-ar-${version} \
+ --slave /usr/bin/llvm-as llvm-as /usr/bin/llvm-as-${version} \
+ --slave /usr/bin/llvm-bcanalyzer llvm-bcanalyzer /usr/bin/llvm-bcanalyzer-${version} \
+ --slave /usr/bin/llvm-cov llvm-cov /usr/bin/llvm-cov-${version} \
+ --slave /usr/bin/llvm-diff llvm-diff /usr/bin/llvm-diff-${version} \
+ --slave /usr/bin/llvm-dis llvm-dis /usr/bin/llvm-dis-${version} \
+ --slave /usr/bin/llvm-dwarfdump llvm-dwarfdump /usr/bin/llvm-dwarfdump-${version} \
+ --slave /usr/bin/llvm-extract llvm-extract /usr/bin/llvm-extract-${version} \
+ --slave /usr/bin/llvm-link llvm-link /usr/bin/llvm-link-${version} \
+ --slave /usr/bin/llvm-mc llvm-mc /usr/bin/llvm-mc-${version} \
+ --slave /usr/bin/llvm-mcmarkup llvm-mcmarkup /usr/bin/llvm-mcmarkup-${version} \
+ --slave /usr/bin/llvm-nm llvm-nm /usr/bin/llvm-nm-${version} \
+ --slave /usr/bin/llvm-objdump llvm-objdump /usr/bin/llvm-objdump-${version} \
+ --slave /usr/bin/llvm-ranlib llvm-ranlib /usr/bin/llvm-ranlib-${version} \
+ --slave /usr/bin/llvm-readobj llvm-readobj /usr/bin/llvm-readobj-${version} \
+ --slave /usr/bin/llvm-rtdyld llvm-rtdyld /usr/bin/llvm-rtdyld-${version} \
+ --slave /usr/bin/llvm-size llvm-size /usr/bin/llvm-size-${version} \
+ --slave /usr/bin/llvm-stress llvm-stress /usr/bin/llvm-stress-${version} \
+ --slave /usr/bin/llvm-symbolizer llvm-symbolizer /usr/bin/llvm-symbolizer-${version} \
+ --slave /usr/bin/llvm-tblgen llvm-tblgen /usr/bin/llvm-tblgen-${version}
+
+ update-alternatives \
+ --install /usr/bin/clang clang /usr/bin/clang-${version} ${priority} \
+ --slave /usr/bin/clang++ clang++ /usr/bin/clang++-${version} \
+ --slave /usr/bin/asan_symbolize asan_symbolize /usr/bin/asan_symbolize-${version} \
+ --slave /usr/bin/c-index-test c-index-test /usr/bin/c-index-test-${version} \
+ --slave /usr/bin/clang-check clang-check /usr/bin/clang-check-${version} \
+ --slave /usr/bin/clang-cl clang-cl /usr/bin/clang-cl-${version} \
+ --slave /usr/bin/clang-cpp clang-cpp /usr/bin/clang-cpp-${version} \
+ --slave /usr/bin/clang-format clang-format /usr/bin/clang-format-${version} \
+ --slave /usr/bin/clang-format-diff clang-format-diff /usr/bin/clang-format-diff-${version} \
+ --slave /usr/bin/clang-import-test clang-import-test /usr/bin/clang-import-test-${version} \
+ --slave /usr/bin/clang-include-fixer clang-include-fixer /usr/bin/clang-include-fixer-${version} \
+ --slave /usr/bin/clang-offload-bundler clang-offload-bundler /usr/bin/clang-offload-bundler-${version} \
+ --slave /usr/bin/clang-query clang-query /usr/bin/clang-query-${version} \
+ --slave /usr/bin/clang-rename clang-rename /usr/bin/clang-rename-${version} \
+ --slave /usr/bin/clang-reorder-fields clang-reorder-fields /usr/bin/clang-reorder-fields-${version} \
+ --slave /usr/bin/clang-tidy clang-tidy /usr/bin/clang-tidy-${version} \
+ --slave /usr/bin/lldb lldb /usr/bin/lldb-${version} \
+ --slave /usr/bin/lldb-server lldb-server /usr/bin/lldb-server-${version}
+
+ # Use clang instead of cc by default
+ update-alternatives --install /usr/bin/cc cc /usr/bin/clang $priority
+}
+
+rename_llvm_binaries $@
diff --git a/framework/Android.bp b/framework/Android.bp
index 5601d9db57..a3bacd226b 100644
--- a/framework/Android.bp
+++ b/framework/Android.bp
@@ -82,10 +82,10 @@ java_sdk_library {
},
}
-// defaults for CTS tests that need to build against framework-bluetooths's @hide APIs
+// defaults for tests that need to build against framework-bluetooths's @hide APIs
java_defaults {
- name: "framework-bluetooth-cts-defaults",
- sdk_version: "core_current",
+ name: "framework-bluetooth-tests-defaults",
+ sdk_version: "core_platform",
libs: [
// order matters: classes in framework-bluetooth are resolved before framework, meaning
// @hide APIs in framework-bluetooth are resolved before @SystemApi stubs in framework
diff --git a/framework/java/android/bluetooth/OWNERS b/framework/OWNERS
index bf15cf08bd..fbee577731 100644
--- a/framework/java/android/bluetooth/OWNERS
+++ b/framework/OWNERS
@@ -1,5 +1,3 @@
-set noparent
-
# Bug component: 27441
rahulsabnis@google.com
diff --git a/framework/api/current.txt b/framework/api/current.txt
index bb9e85e11c..659323fe54 100644
--- a/framework/api/current.txt
+++ b/framework/api/current.txt
@@ -17,8 +17,8 @@ package android.bluetooth {
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public boolean cancelDiscovery();
method public static boolean checkBluetoothAddress(String);
method public void closeProfileProxy(int, android.bluetooth.BluetoothProfile);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean disable();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean enable();
+ method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean disable();
+ method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean enable();
method public String getAddress();
method public android.bluetooth.le.BluetoothLeAdvertiser getBluetoothLeAdvertiser();
method public android.bluetooth.le.BluetoothLeScanner getBluetoothLeScanner();
diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt
index 43e1792c26..a47cc0a506 100644
--- a/framework/api/system-current.txt
+++ b/framework/api/system-current.txt
@@ -54,7 +54,6 @@ package android.bluetooth {
public final class BluetoothAdapter {
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean addOnMetadataChangedListener(@NonNull android.bluetooth.BluetoothDevice, @NonNull java.util.concurrent.Executor, @NonNull android.bluetooth.BluetoothAdapter.OnMetadataChangedListener);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int closeRfcommServer(@NonNull java.util.UUID);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean disable(boolean);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean disableBLE();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean enableBLE();
@@ -80,6 +79,7 @@ package android.bluetooth {
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int setDiscoverableTimeout(@NonNull java.time.Duration);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int setScanMode(int);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int startRfcommServer(@NonNull String, @NonNull java.util.UUID, @NonNull android.app.PendingIntent);
+ method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int stopRfcommServer(@NonNull java.util.UUID);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean unregisterBluetoothConnectionCallback(@NonNull android.bluetooth.BluetoothAdapter.BluetoothConnectionCallback);
method public void unregisterServiceLifecycleCallback(@NonNull android.bluetooth.BluetoothAdapter.ServiceLifecycleCallback);
field public static final String ACTION_BLE_STATE_CHANGED = "android.bluetooth.adapter.action.BLE_STATE_CHANGED";
@@ -88,6 +88,7 @@ package android.bluetooth {
field public static final int ACTIVE_DEVICE_ALL = 2; // 0x2
field public static final int ACTIVE_DEVICE_AUDIO = 0; // 0x0
field public static final int ACTIVE_DEVICE_PHONE_CALL = 1; // 0x1
+ field public static final String EXTRA_RFCOMM_LISTENER_ID = "android.bluetooth.adapter.extra.RFCOMM_LISTENER_ID";
field public static final int STATE_BLE_ON = 15; // 0xf
}
@@ -151,7 +152,6 @@ package android.bluetooth {
public final class BluetoothDevice implements android.os.Parcelable {
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean canBondWithoutDialog();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean cancelBondProcess();
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean cancelPairing();
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.MODIFY_PHONE_STATE}) public int connect();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean createBond(int);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean createBondOutOfBand(int, @Nullable android.bluetooth.OobData, @Nullable android.bluetooth.OobData);
@@ -301,10 +301,10 @@ package android.bluetooth {
public static final class BluetoothHapPresetInfo.Builder {
ctor public BluetoothHapPresetInfo.Builder();
method @NonNull public android.bluetooth.BluetoothHapPresetInfo build();
- method @NonNull public android.bluetooth.BluetoothHapPresetInfo.Builder setAvailable(@NonNull boolean);
+ method @NonNull public android.bluetooth.BluetoothHapPresetInfo.Builder setAvailable(boolean);
method @NonNull public android.bluetooth.BluetoothHapPresetInfo.Builder setIndex(int);
method @NonNull public android.bluetooth.BluetoothHapPresetInfo.Builder setName(@NonNull String);
- method @NonNull public android.bluetooth.BluetoothHapPresetInfo.Builder setWritable(@NonNull boolean);
+ method @NonNull public android.bluetooth.BluetoothHapPresetInfo.Builder setWritable(boolean);
}
public final class BluetoothHeadset implements android.bluetooth.BluetoothProfile {
@@ -328,14 +328,26 @@ package android.bluetooth {
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice);
method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(@NonNull int[]);
+ method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public android.bluetooth.BluetoothHeadsetClient.NetworkServiceState getNetworkServiceState(@NonNull android.bluetooth.BluetoothDevice);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_AUDIO_STATE_CHANGED = "android.bluetooth.headsetclient.profile.action.AUDIO_STATE_CHANGED";
field @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.headsetclient.profile.action.CONNECTION_STATE_CHANGED";
+ field @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public static final String ACTION_NETWORK_SERVICE_STATE_CHANGED = "android.bluetooth.headsetclient.profile.action.NETWORK_SERVICE_STATE_CHANGED";
+ field public static final String EXTRA_NETWORK_SERVICE_STATE = "android.bluetooth.headsetclient.extra.EXTRA_NETWORK_SERVICE_STATE";
field public static final int STATE_AUDIO_CONNECTED = 2; // 0x2
field public static final int STATE_AUDIO_CONNECTING = 1; // 0x1
field public static final int STATE_AUDIO_DISCONNECTED = 0; // 0x0
}
+ public static final class BluetoothHeadsetClient.NetworkServiceState implements android.os.Parcelable {
+ method @NonNull public android.bluetooth.BluetoothDevice getDevice();
+ method @Nullable public String getOperatorName();
+ method public int getSignalStrength();
+ method public boolean isRoaming();
+ method public boolean isServiceAvailable();
+ field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothHeadsetClient.NetworkServiceState> CREATOR;
+ }
+
public final class BluetoothHearingAid implements android.bluetooth.BluetoothProfile {
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public long getHiSyncId(@NonNull android.bluetooth.BluetoothDevice);
@@ -604,8 +616,8 @@ package android.bluetooth {
}
public interface BluetoothProfile {
- method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public static String getConnectionStateName(int);
- method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public static String getProfileName(int);
+ method @NonNull public static String getConnectionStateName(int);
+ method @NonNull public static String getProfileName(int);
field public static final int A2DP_SINK = 11; // 0xb
field public static final int AVRCP_CONTROLLER = 12; // 0xc
field public static final int CONNECTION_POLICY_ALLOWED = 100; // 0x64
@@ -660,7 +672,7 @@ package android.bluetooth {
field public static final int ERROR_PROFILE_NOT_CONNECTED = 14; // 0xe
field public static final int ERROR_REMOTE_LINK_ERROR = 25; // 0x19
field public static final int ERROR_REMOTE_NOT_ENOUGH_RESOURCES = 23; // 0x17
- field public static final int ERROR_REMOTE_OPERATION_NOT_SUPPORTED = 24; // 0x18
+ field public static final int ERROR_REMOTE_OPERATION_NOT_SUPPORTED = 27; // 0x1b
field public static final int ERROR_REMOTE_OPERATION_REJECTED = 24; // 0x18
field public static final int ERROR_TIMEOUT = 15; // 0xf
field public static final int NOT_ALLOWED = 401; // 0x191
@@ -685,6 +697,7 @@ package android.bluetooth {
field @NonNull public static final android.os.ParcelUuid AVRCP_CONTROLLER;
field @NonNull public static final android.os.ParcelUuid AVRCP_TARGET;
field @NonNull public static final android.os.ParcelUuid BASE_UUID;
+ field @NonNull public static final android.os.ParcelUuid BASS;
field @NonNull public static final android.os.ParcelUuid BNEP;
field @NonNull public static final android.os.ParcelUuid CAP;
field @NonNull public static final android.os.ParcelUuid COORDINATED_SET;
diff --git a/framework/java/android/bluetooth/BluetoothAdapter.java b/framework/java/android/bluetooth/BluetoothAdapter.java
index 05c67f360a..dc7ffa6fd2 100644
--- a/framework/java/android/bluetooth/BluetoothAdapter.java
+++ b/framework/java/android/bluetooth/BluetoothAdapter.java
@@ -251,6 +251,8 @@ public final class BluetoothAdapter {
*
* @hide
*/
+ @SystemApi
+ @SuppressLint("ActionValue")
public static final String EXTRA_RFCOMM_LISTENER_ID =
"android.bluetooth.adapter.extra.RFCOMM_LISTENER_ID";
@@ -1137,9 +1139,7 @@ public final class BluetoothAdapter {
try {
final SynchronousResultReceiver<Integer> recv =
new SynchronousResultReceiver();
- if (mService != null) {
- mService.getState(recv);
- }
+ mService.getState(recv);
return recv.awaitResultNoInterrupt(getSyncTimeout())
.getValue(BluetoothAdapter.STATE_OFF);
} catch (TimeoutException e) {
@@ -1183,11 +1183,8 @@ public final class BluetoothAdapter {
mService.getState(recv);
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(state);
}
- } catch (TimeoutException e) {
+ } catch (RemoteException | TimeoutException e) {
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- e.rethrowFromSystemServer();
} finally {
mServiceLock.readLock().unlock();
}
@@ -1289,7 +1286,20 @@ public final class BluetoothAdapter {
* such as Airplane mode, or the adapter is already turned on.
*
* @return true to indicate adapter startup has begun, or false on immediate error
+ *
+ * @deprecated Starting with {@link android.os.Build.VERSION_CODES#TIRAMISU}, applications
+ * are not allowed to enable/disable Bluetooth.
+ * <b>Compatibility Note:</b> For applications targeting
+ * {@link android.os.Build.VERSION_CODES#TIRAMISU} or above, this API will always fail and return
+ * {@code false}. If apps are targeting an older SDK ({@link android.os.Build.VERSION_CODES#S}
+ * or below), they can continue to use this API.
+ * <p>
+ * Deprecation Exemptions:
+ * <ul>
+ * <li>Device Owner (DO), Profile Owner (PO) and system apps.
+ * </ul>
*/
+ @Deprecated
@RequiresLegacyBluetoothAdminPermission
@RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
@@ -1329,7 +1339,20 @@ public final class BluetoothAdapter {
* such as the adapter already being turned off.
*
* @return true to indicate adapter shutdown has begun, or false on immediate error
+ *
+ * @deprecated Starting with {@link android.os.Build.VERSION_CODES#TIRAMISU}, applications
+ * are not allowed to enable/disable Bluetooth.
+ * <b>Compatibility Note:</b> For applications targeting
+ * {@link android.os.Build.VERSION_CODES#TIRAMISU} or above, this API will always fail and return
+ * {@code false}. If apps are targeting an older SDK ({@link android.os.Build.VERSION_CODES#S}
+ * or below), they can continue to use this API.
+ * <p>
+ * Deprecation Exemptions:
+ * <ul>
+ * <li>Device Owner (DO), Profile Owner (PO) and system apps.
+ * </ul>
*/
+ @Deprecated
@RequiresLegacyBluetoothAdminPermission
@RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
@@ -3139,7 +3162,7 @@ public final class BluetoothAdapter {
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
})
@RfcommListenerResult
- public int closeRfcommServer(@NonNull UUID uuid) {
+ public int stopRfcommServer(@NonNull UUID uuid) {
try {
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
mService.stopRfcommListener(new ParcelUuid(uuid), mAttributionSource, recv);
diff --git a/framework/java/android/bluetooth/BluetoothClass.java b/framework/java/android/bluetooth/BluetoothClass.java
index 699c80e5b6..fb13be4672 100755
--- a/framework/java/android/bluetooth/BluetoothClass.java
+++ b/framework/java/android/bluetooth/BluetoothClass.java
@@ -18,7 +18,6 @@ package android.bluetooth;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Build;
import android.os.Parcel;
@@ -307,7 +306,6 @@ public final class BluetoothClass implements Parcelable {
*
* @hide
*/
- @TestApi
public int getClassOfDevice() {
return mClass;
}
diff --git a/framework/java/android/bluetooth/BluetoothDevice.java b/framework/java/android/bluetooth/BluetoothDevice.java
index 2b335abc84..9caed4ccac 100644
--- a/framework/java/android/bluetooth/BluetoothDevice.java
+++ b/framework/java/android/bluetooth/BluetoothDevice.java
@@ -2545,39 +2545,6 @@ public final class BluetoothDevice implements Parcelable, Attributable {
return defaultValue;
}
- /**
- * Cancels pairing to this device
- *
- * @return true if pairing cancelled successfully, false otherwise
- *
- * @hide
- */
- @SystemApi
- @RequiresLegacyBluetoothAdminPermission
- @RequiresBluetoothConnectPermission
- @RequiresPermission(allOf = {
- android.Manifest.permission.BLUETOOTH_CONNECT,
- android.Manifest.permission.BLUETOOTH_PRIVILEGED,
- })
- public boolean cancelPairing() {
- if (DBG) log("cancelPairing()");
- final IBluetooth service = sService;
- final boolean defaultValue = false;
- if (service == null) {
- Log.e(TAG, "BT not enabled. Cannot cancel pairing");
- if (DBG) log(Log.getStackTraceString(new Throwable()));
- } else {
- try {
- final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
- service.cancelBondProcess(this, mAttributionSource, recv);
- return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
- } catch (RemoteException | TimeoutException e) {
- Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
- }
- }
- return defaultValue;
- }
-
boolean isBluetoothEnabled() {
boolean ret = false;
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
diff --git a/framework/java/android/bluetooth/BluetoothHapClient.java b/framework/java/android/bluetooth/BluetoothHapClient.java
index 2b245bcb41..fd769d412b 100644
--- a/framework/java/android/bluetooth/BluetoothHapClient.java
+++ b/framework/java/android/bluetooth/BluetoothHapClient.java
@@ -25,6 +25,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
import android.content.AttributionSource;
@@ -39,7 +40,9 @@ import com.android.modules.utils.SynchronousResultReceiver;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeoutException;
@@ -58,6 +61,8 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
private static final boolean DBG = false;
private static final boolean VDBG = false;
+ private final Map<Callback, Executor> mCallbackExecutorMap = new HashMap<>();
+
private CloseGuard mCloseGuard;
/**
@@ -83,17 +88,6 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
})
@interface Status {}
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(value = {
- PRESET_INFO_REASON_ALL_PRESET_INFO,
- PRESET_INFO_REASON_PRESET_INFO_UPDATE,
- PRESET_INFO_REASON_PRESET_DELETED,
- PRESET_INFO_REASON_PRESET_AVAILABILITY_CHANGED,
- PRESET_INFO_REASON_PRESET_INFO_REQUEST_RESPONSE,
- })
- @interface PresetInfoReason {}
-
/**
* Invoked to inform about HA device's currently active preset.
*
@@ -180,6 +174,87 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
void onSetPresetNameForGroupFailed(int hapGroupId, @Status int status);
}
+ @SuppressLint("AndroidFrameworkBluetoothPermission")
+ private final IBluetoothHapClientCallback mCallback = new IBluetoothHapClientCallback.Stub() {
+ @Override
+ public void onActivePresetChanged(@NonNull BluetoothDevice device, int presetIndex) {
+ Attributable.setAttributionSource(device, mAttributionSource);
+ for (Map.Entry<BluetoothHapClient.Callback, Executor> callbackExecutorEntry:
+ mCallbackExecutorMap.entrySet()) {
+ BluetoothHapClient.Callback callback = callbackExecutorEntry.getKey();
+ Executor executor = callbackExecutorEntry.getValue();
+ executor.execute(() -> callback.onActivePresetChanged(device, presetIndex));
+ }
+ }
+
+ @Override
+ public void onSelectActivePresetFailed(@NonNull BluetoothDevice device, int status) {
+ Attributable.setAttributionSource(device, mAttributionSource);
+ for (Map.Entry<BluetoothHapClient.Callback, Executor> callbackExecutorEntry:
+ mCallbackExecutorMap.entrySet()) {
+ BluetoothHapClient.Callback callback = callbackExecutorEntry.getKey();
+ Executor executor = callbackExecutorEntry.getValue();
+ executor.execute(() -> callback.onSelectActivePresetFailed(device, status));
+ }
+ }
+
+ @Override
+ public void onSelectActivePresetForGroupFailed(int hapGroupId, int statusCode) {
+ for (Map.Entry<BluetoothHapClient.Callback, Executor> callbackExecutorEntry:
+ mCallbackExecutorMap.entrySet()) {
+ BluetoothHapClient.Callback callback = callbackExecutorEntry.getKey();
+ Executor executor = callbackExecutorEntry.getValue();
+ executor.execute(
+ () -> callback.onSelectActivePresetForGroupFailed(hapGroupId, statusCode));
+ }
+ }
+
+ @Override
+ public void onPresetInfoChanged(@NonNull BluetoothDevice device,
+ @NonNull List<BluetoothHapPresetInfo> presetInfoList, int statusCode) {
+ Attributable.setAttributionSource(device, mAttributionSource);
+ for (Map.Entry<BluetoothHapClient.Callback, Executor> callbackExecutorEntry:
+ mCallbackExecutorMap.entrySet()) {
+ BluetoothHapClient.Callback callback = callbackExecutorEntry.getKey();
+ Executor executor = callbackExecutorEntry.getValue();
+ executor.execute(
+ () -> callback.onPresetInfoChanged(device, presetInfoList, statusCode));
+ }
+ }
+
+ @Override
+ public void onHapFeaturesAvailable(@NonNull BluetoothDevice device, int hapFeatures) {
+ Attributable.setAttributionSource(device, mAttributionSource);
+ for (Map.Entry<BluetoothHapClient.Callback, Executor> callbackExecutorEntry:
+ mCallbackExecutorMap.entrySet()) {
+ BluetoothHapClient.Callback callback = callbackExecutorEntry.getKey();
+ Executor executor = callbackExecutorEntry.getValue();
+ executor.execute(() -> callback.onHapFeaturesAvailable(device, hapFeatures));
+ }
+ }
+
+ @Override
+ public void onSetPresetNameFailed(@NonNull BluetoothDevice device, int status) {
+ Attributable.setAttributionSource(device, mAttributionSource);
+ for (Map.Entry<BluetoothHapClient.Callback, Executor> callbackExecutorEntry:
+ mCallbackExecutorMap.entrySet()) {
+ BluetoothHapClient.Callback callback = callbackExecutorEntry.getKey();
+ Executor executor = callbackExecutorEntry.getValue();
+ executor.execute(() -> callback.onSetPresetNameFailed(device, status));
+ }
+ }
+
+ @Override
+ public void onSetPresetNameForGroupFailed(int hapGroupId, int status) {
+ for (Map.Entry<BluetoothHapClient.Callback, Executor> callbackExecutorEntry:
+ mCallbackExecutorMap.entrySet()) {
+ BluetoothHapClient.Callback callback = callbackExecutorEntry.getKey();
+ Executor executor = callbackExecutorEntry.getValue();
+ executor.execute(() -> callback.onSetPresetNameForGroupFailed(hapGroupId, status));
+ }
+ }
+ };
+
/**
* Intent used to broadcast the change in connection state of the Hearing Access Profile Client
* service. Please note that in the binaural case, there will be two different LE devices for
@@ -229,235 +304,12 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
"android.bluetooth.action.HAP_DEVICE_AVAILABLE";
/**
- * Intent used to broadcast HA device's feature set.
- *
- * <p>This intent will have 2 extras:
- * <ul>
- * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
- * <li> {@link #EXTRA_HAP_FEATURES}- The feature set integer with these possible bit numbers
- * set: {@link #FEATURE_BIT_NUM_TYPE_MONAURAL}, {@link #FEATURE_BIT_NUM_TYPE_BANDED},
- * {@link #FEATURE_BIT_NUM_SYNCHRONIZATED_PRESETS},
- * {@link #FEATURE_BIT_NUM_INDEPENDENT_PRESETS}, {@link #FEATURE_BIT_NUM_DYNAMIC_PRESETS},
- * {@link #FEATURE_BIT_NUM_WRITABLE_PRESETS}.</li>
- * </ul>
- *
- * @hide
- */
- @RequiresPermission(allOf = {
- android.Manifest.permission.BLUETOOTH_CONNECT,
- android.Manifest.permission.BLUETOOTH_PRIVILEGED,
- })
- @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_HAP_ON_DEVICE_FEATURES =
- "android.bluetooth.action.HAP_ON_DEVICE_FEATURES";
-
- /**
- * Intent used to broadcast the change of a HA device's active preset.
- *
- * <p>This intent will have 2 extras:
- * <ul>
- * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
- * <li> {@link #EXTRA_HAP_PRESET_INDEX}- The currently active preset.</li>
- * </ul>
- *
- * @hide
- */
- @RequiresPermission(allOf = {
- android.Manifest.permission.BLUETOOTH_CONNECT,
- android.Manifest.permission.BLUETOOTH_PRIVILEGED,
- })
- @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_HAP_ON_ACTIVE_PRESET =
- "android.bluetooth.action.HAP_ON_ACTIVE_PRESET";
-
- /**
- * Intent used to broadcast the result of a failed preset change attempt.
- *
- * <p>This intent will have 2 extras:
- * <ul>
- * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
- * <li> {@link #EXTRA_HAP_STATUS_CODE}- Failure reason.</li>
- * </ul>
- *
- * <p>{@link #EXTRA_HAP_STATUS_CODE} can be any of {@link #STATUS_INVALID_PRESET_INDEX},
- * {@link #STATUS_OPERATION_NOT_POSSIBLE},{@link #STATUS_OPERATION_NOT_SUPPORTED}.
- *
- * @hide
- */
- @RequiresPermission(allOf = {
- android.Manifest.permission.BLUETOOTH_CONNECT,
- android.Manifest.permission.BLUETOOTH_PRIVILEGED,
- })
- @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_HAP_ON_ACTIVE_PRESET_SELECT_ERROR =
- "android.bluetooth.action.HAP_ON_ACTIVE_PRESET_SELECT_ERROR";
-
- /**
- * Intent used to broadcast preset name change.
- *
- * <p>This intent will have 4 extras:
- * <ul>
- * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
- * <li> {@link #EXTRA_HAP_PRESET_INFO}- List of preset informations </li>
- * <li> {@link #EXTRA_HAP_PRESET_INFO_REASON}- Why this preset info notification was sent </li>
- * notifications or the user should expect more to come. </li>
- * </ul>
- *
- * @hide
- */
- @RequiresPermission(allOf = {
- android.Manifest.permission.BLUETOOTH_CONNECT,
- android.Manifest.permission.BLUETOOTH_PRIVILEGED,
- })
- @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_HAP_ON_PRESET_INFO =
- "android.bluetooth.action.HAP_ON_PRESET_INFO";
-
- /**
- * Intent used to broadcast result of a failed rename attempt.
- *
- * <p>This intent will have 3 extras:
- * <ul>
- * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
- * <li> {@link #EXTRA_HAP_PRESET_INDEX}- The currently active preset.</li>
- * <li> {@link #EXTRA_HAP_STATUS_CODE}- Failure reason code.</li>
- * </ul>
- *
- * <p>{@link #EXTRA_HAP_STATUS_CODE} can be any of {@link #STATUS_SET_NAME_NOT_ALLOWED},
- * {@link #STATUS_INVALID_PRESET_INDEX}, {@link #STATUS_INVALID_PRESET_NAME_LENGTH}.
- *
- * @hide
- */
- @RequiresPermission(allOf = {
- android.Manifest.permission.BLUETOOTH_CONNECT,
- android.Manifest.permission.BLUETOOTH_PRIVILEGED,
- })
- @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_HAP_ON_PRESET_NAME_SET_ERROR =
- "android.bluetooth.action.HAP_ON_PRESET_NAME_SET_ERROR";
-
- /**
- * Intent used to broadcast the result of a failed name get attempt.
- *
- * <p>This intent will have 3 extras:
- * <ul>
- * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
- * <li> {@link #EXTRA_HAP_PRESET_INDEX}- The currently active preset.</li>
- * <li> {@link #EXTRA_HAP_STATUS_CODE}- Failure reason code.</li>
- * </ul>
- *
- * <p>{@link #EXTRA_HAP_STATUS_CODE} can be any of {@link #STATUS_INVALID_PRESET_INDEX},
- * {@link #STATUS_OPERATION_NOT_POSSIBLE}.
- *
- * @hide
- */
- @RequiresPermission(allOf = {
- android.Manifest.permission.BLUETOOTH_CONNECT,
- android.Manifest.permission.BLUETOOTH_PRIVILEGED,
- })
- @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_HAP_ON_PRESET_INFO_GET_ERROR =
- "android.bluetooth.action.HAP_ON_PRESET_INFO_GET_ERROR";
-
- /**
* Contains a list of all available presets
* @hide
*/
public static final String EXTRA_HAP_FEATURES = "android.bluetooth.extra.HAP_FEATURES";
/**
- * Contains a preset identifier
- * @hide
- */
- public static final String EXTRA_HAP_PRESET_INDEX = "android.bluetooth.extra.HAP_PRESET_INDEX";
-
- /**
- * Used to report failure reasons.
- * @hide
- */
- public static final String EXTRA_HAP_STATUS_CODE = "android.bluetooth.extra.HAP_STATUS_CODE";
-
- /**
- * Used by group events.
- * @hide
- */
- public static final String EXTRA_HAP_GROUP_ID = "android.bluetooth.extra.HAP_GROUP_ID";
-
- /**
- * Preset Info reason.
- * Possible values:
- * {@link #PRESET_INFO_REASON_ALL_PRESET_INFO} or
- * {@link #PRESET_INFO_REASON_PRESET_INFO_UPDATE} or
- * {@link #PRESET_INFO_REASON_PRESET_DELETED} or
- * {@link #PRESET_INFO_REASON_PRESET_AVAILABILITY_CHANGED} or
- * {@link #PRESET_INFO_REASON_PRESET_INFO_REQUEST_RESPONSE}
- * @hide
- */
- public static final String EXTRA_HAP_PRESET_INFO_REASON =
- "android.bluetooth.extra.HAP_PRESET_INFO_REASON";
-
- /**
- * Preset Info.
- * @hide
- */
- public static final String EXTRA_HAP_PRESET_INFO = "android.bluetooth.extra.HAP_PRESET_INFO";
-
- /**
- * Preset name change failure due to preset being read-only.
- * @hide
- */
- public static final int STATUS_SET_NAME_NOT_ALLOWED =
- IBluetoothHapClient.STATUS_SET_NAME_NOT_ALLOWED;
-
- /**
- * Means that the requested operation is not supported by the HA device.
- *
- * <p> It could mean that the requested name change is not supported on
- * a given preset or the device does not support presets at all.
- * @hide
- */
- public static final int STATUS_OPERATION_NOT_SUPPORTED =
- IBluetoothHapClient.STATUS_OPERATION_NOT_SUPPORTED;
-
- /**
- * Usually means a temporary denial of certain operation. Peer device may report this
- * status due to various implementation specific reasons. It's different than
- * the {@link #STATUS_OPERATION_NOT_SUPPORTED} which represents more of a
- * permanent inability to perform some of the operations.
- * @hide
- */
- public static final int STATUS_OPERATION_NOT_POSSIBLE =
- IBluetoothHapClient.STATUS_OPERATION_NOT_POSSIBLE;
-
- /**
- * Used when preset name change failed due to the passed name parameter being to long.
- * @hide
- */
- public static final int STATUS_INVALID_PRESET_NAME_LENGTH =
- IBluetoothHapClient.STATUS_INVALID_PRESET_NAME_LENGTH;
-
- /**
- * Group operations are not supported.
- * @hide
- */
- public static final int STATUS_GROUP_OPERATION_NOT_SUPPORTED =
- IBluetoothHapClient.STATUS_GROUP_OPERATION_NOT_SUPPORTED;
-
- /**
- * Procedure is already in progress.
- * @hide
- */
- public static final int STATUS_PROCEDURE_ALREADY_IN_PROGRESS =
- IBluetoothHapClient.STATUS_PROCEDURE_ALREADY_IN_PROGRESS;
-
- /**
- * Invalid preset index input parameter used in one of the API calls.
- * @hide
- */
- public static final int STATUS_INVALID_PRESET_INDEX =
- IBluetoothHapClient.STATUS_INVALID_PRESET_INDEX;
-
- /**
* Represets an invalid index value. This is usually value returned in a currently
* active preset request for a device which is not connected. This value shouldn't be used
* in the API calls.
@@ -507,48 +359,6 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
public static final int FEATURE_BIT_NUM_WRITABLE_PRESETS =
IBluetoothHapClient.FEATURE_BIT_NUM_WRITABLE_PRESETS;
- /**
- * Preset Info notification reason.
- * @hide
- */
- public static final int PRESET_INFO_REASON_ALL_PRESET_INFO =
- IBluetoothHapClient.PRESET_INFO_REASON_ALL_PRESET_INFO;
-
- /**
- * Preset Info notification reason.
- * @hide
- */
- public static final int PRESET_INFO_REASON_PRESET_INFO_UPDATE =
- IBluetoothHapClient.PRESET_INFO_REASON_PRESET_INFO_UPDATE;
-
- /**
- * Preset Info notification reason.
- * @hide
- */
- public static final int PRESET_INFO_REASON_PRESET_DELETED =
- IBluetoothHapClient.PRESET_INFO_REASON_PRESET_DELETED;
-
- /**
- * Preset Info notification reason.
- * @hide
- */
- public static final int PRESET_INFO_REASON_PRESET_AVAILABILITY_CHANGED =
- IBluetoothHapClient.PRESET_INFO_REASON_PRESET_AVAILABILITY_CHANGED;
-
- /**
- * Preset Info notification reason.
- * @hide
- */
- public static final int PRESET_INFO_REASON_PRESET_INFO_REQUEST_RESPONSE =
- IBluetoothHapClient.PRESET_INFO_REASON_PRESET_INFO_REQUEST_RESPONSE;
-
- /**
- * Represents invalid group identifier. It's returned when user requests a group identifier
- * for a device which is not part of any group. This value shouldn't be used in the API calls.
- * @hide
- */
- public static final int HAP_GROUP_UNAVAILABLE = IBluetoothHapClient.GROUP_ID_UNAVAILABLE;
-
private final BluetoothAdapter mAdapter;
private final AttributionSource mAttributionSource;
private final BluetoothProfileConnector<IBluetoothHapClient> mProfileConnector =
@@ -560,6 +370,35 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
}
};
+ @SuppressLint("AndroidFrameworkBluetoothPermission")
+ private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
+ new IBluetoothStateChangeCallback.Stub() {
+ public void onBluetoothStateChange(boolean up) {
+ if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
+ if (up) {
+ // re-register the service-to-app callback
+ synchronized (mCallbackExecutorMap) {
+ if (mCallbackExecutorMap.isEmpty()) return;
+
+ try {
+ final IBluetoothHapClient service = getService();
+ if (service != null) {
+ final SynchronousResultReceiver<Integer> recv =
+ new SynchronousResultReceiver();
+ service.registerCallback(mCallback, mAttributionSource, recv);
+ recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
+ }
+ } catch (TimeoutException e) {
+ Log.e(TAG, e.toString() + "\n"
+ + Log.getStackTraceString(new Throwable()));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
+ }
+ };
+
/**
* Create a BluetoothHapClient proxy object for interacting with the local
* Bluetooth Hearing Access Profile (HAP) client.
@@ -568,6 +407,16 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
mAdapter = BluetoothAdapter.getDefaultAdapter();
mAttributionSource = mAdapter.getAttributionSource();
mProfileConnector.connect(context, listener);
+
+ IBluetoothManager mgr = mAdapter.getBluetoothManager();
+ if (mgr != null) {
+ try {
+ mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
mCloseGuard = new CloseGuard();
mCloseGuard.open("close");
}
@@ -586,6 +435,17 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
* @hide
*/
public void close() {
+ if (VDBG) log("close()");
+
+ IBluetoothManager mgr = mAdapter.getBluetoothManager();
+ if (mgr != null) {
+ try {
+ mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
+ }
+
mProfileConnector.disconnect();
}
@@ -621,8 +481,36 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
if (callback == null) {
throw new IllegalArgumentException("callback cannot be null");
}
+ if (!isEnabled()) {
+ throw new IllegalStateException("service not enabled");
+ }
+
if (DBG) log("registerCallback");
- throw new UnsupportedOperationException("Not Implemented");
+
+ synchronized (mCallbackExecutorMap) {
+ // If the callback map is empty, we register the service-to-app callback
+ if (mCallbackExecutorMap.isEmpty()) {
+ try {
+ final IBluetoothHapClient service = getService();
+ if (service != null) {
+ final SynchronousResultReceiver<Integer> recv =
+ new SynchronousResultReceiver();
+ service.registerCallback(mCallback, mAttributionSource, recv);
+ recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
+ }
+ } catch (IllegalStateException | TimeoutException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ // Adds the passed in callback to our map of callbacks to executors
+ if (mCallbackExecutorMap.containsKey(callback)) {
+ throw new IllegalArgumentException("This callback has already been registered");
+ }
+ mCallbackExecutorMap.put(callback, executor);
+ }
}
/**
@@ -646,8 +534,30 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
if (callback == null) {
throw new IllegalArgumentException("callback cannot be null");
}
+
if (DBG) log("unregisterCallback");
- throw new UnsupportedOperationException("Not Implemented");
+
+ synchronized (mCallbackExecutorMap) {
+ if (mCallbackExecutorMap.remove(callback) != null) {
+ throw new IllegalArgumentException("This callback has not been registered");
+ }
+ }
+
+ // If the callback map is empty, we unregister the service-to-app callback
+ if (mCallbackExecutorMap.isEmpty()) {
+ try {
+ final IBluetoothHapClient service = getService();
+ if (service != null) {
+ final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
+ service.unregisterCallback(mCallback, mAttributionSource, recv);
+ recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
+ }
+ } catch (TimeoutException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
/**
@@ -683,8 +593,10 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
- } catch (RemoteException | TimeoutException e) {
+ } catch (TimeoutException e) {
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
return defaultValue;
@@ -719,8 +631,10 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
service.getConnectionPolicy(device, mAttributionSource, recv);
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
- } catch (RemoteException | TimeoutException e) {
+ } catch (TimeoutException e) {
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
return defaultValue;
@@ -748,9 +662,13 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
try {
final SynchronousResultReceiver<List> recv = new SynchronousResultReceiver();
service.getConnectedDevices(mAttributionSource, recv);
- return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
- } catch (RemoteException | TimeoutException e) {
+ return Attributable.setAttributionSource(
+ recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
+ mAttributionSource);
+ } catch (TimeoutException e) {
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
return defaultValue;
@@ -779,9 +697,13 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
try {
final SynchronousResultReceiver<List> recv = new SynchronousResultReceiver();
service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
- return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
- } catch (RemoteException | TimeoutException e) {
+ return Attributable.setAttributionSource(
+ recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
+ mAttributionSource);
+ } catch (TimeoutException e) {
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
return defaultValue;
@@ -811,8 +733,10 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
service.getConnectionState(device, mAttributionSource, recv);
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
- } catch (RemoteException | TimeoutException e) {
+ } catch (TimeoutException e) {
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
return defaultValue;
@@ -828,12 +752,11 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
* require individual device calls.
*
* <p>Note that some binaural HA devices may not support group operations,
- * therefore are not considered a valid HAP group. In such case the
- * {@link #HAP_GROUP_UNAVAILABLE} is returned even when such
- * device is a valid Le Audio Coordinated Set member.
+ * therefore are not considered a valid HAP group. In such case -1 is returned
+ * even if such device is a valid Le Audio Coordinated Set member.
*
* @param device
- * @return valid group identifier or {@link #HAP_GROUP_UNAVAILABLE}
+ * @return valid group identifier or -1
* @hide
*/
@RequiresBluetoothConnectPermission
@@ -843,7 +766,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
})
public int getHapGroup(@NonNull BluetoothDevice device) {
final IBluetoothHapClient service = getService();
- final int defaultValue = HAP_GROUP_UNAVAILABLE;
+ final int defaultValue = BluetoothCsipSetCoordinator.GROUP_ID_INVALID;
if (service == null) {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -852,8 +775,10 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
service.getHapGroup(device, mAttributionSource, recv);
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
- } catch (RemoteException | TimeoutException e) {
+ } catch (TimeoutException e) {
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
return defaultValue;
@@ -878,14 +803,15 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
} else if (isEnabled() && isValidDevice(device)) {
- // TODO(b/216639668)
- // try {
- // final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
- // service.getActivePresetIndex(device, mAttributionSource, recv);
- // return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
- // } catch (RemoteException | TimeoutException e) {
- // Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
- // }
+ try {
+ final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
+ service.getActivePresetIndex(device, mAttributionSource, recv);
+ return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
+ } catch (TimeoutException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
return defaultValue;
}
@@ -905,8 +831,25 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
android.Manifest.permission.BLUETOOTH_PRIVILEGED
})
public @Nullable BluetoothHapPresetInfo getActivePresetInfo(@NonNull BluetoothDevice device) {
- // TODO(b/216639668)
- return null;
+ final IBluetoothHapClient service = getService();
+ final BluetoothHapPresetInfo defaultValue = null;
+ if (service == null) {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) log(Log.getStackTraceString(new Throwable()));
+ } else if (isEnabled() && isValidDevice(device)) {
+ try {
+ final SynchronousResultReceiver<BluetoothHapPresetInfo> recv =
+ new SynchronousResultReceiver();
+ service.getActivePresetInfo(device, mAttributionSource, recv);
+ recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
+ } catch (TimeoutException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ return defaultValue;
}
/**
@@ -928,18 +871,14 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
})
public void selectPreset(@NonNull BluetoothDevice device, int presetIndex) {
final IBluetoothHapClient service = getService();
- final boolean defaultValue = false;
if (service == null) {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
} else if (isEnabled() && isValidDevice(device)) {
try {
- // TODO(b/216639668)
- final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
- service.selectActivePreset(device, presetIndex, mAttributionSource, recv);
- recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
- } catch (RemoteException | TimeoutException e) {
- Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ service.selectPreset(device, presetIndex, mAttributionSource);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
}
@@ -968,18 +907,14 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
})
public void selectPresetForGroup(int groupId, int presetIndex) {
final IBluetoothHapClient service = getService();
- final boolean defaultValue = false;
if (service == null) {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
} else if (isEnabled()) {
try {
- // TODO(b/216639668)
- final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
- service.groupSelectActivePreset(groupId, presetIndex, mAttributionSource, recv);
- recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
- } catch (RemoteException | TimeoutException e) {
- Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ service.selectPresetForGroup(groupId, presetIndex, mAttributionSource);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
}
@@ -1000,18 +935,14 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
})
public void switchToNextPreset(@NonNull BluetoothDevice device) {
final IBluetoothHapClient service = getService();
- final boolean defaultValue = false;
if (service == null) {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
} else if (isEnabled() && isValidDevice(device)) {
try {
- // TODO(b/216639668)
- final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
- service.nextActivePreset(device, mAttributionSource, recv);
- recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
- } catch (RemoteException | TimeoutException e) {
- Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ service.switchToNextPreset(device, mAttributionSource);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
}
@@ -1034,18 +965,14 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
})
public void switchToNextPresetForGroup(int groupId) {
final IBluetoothHapClient service = getService();
- final boolean defaultValue = false;
if (service == null) {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
} else if (isEnabled()) {
try {
- // TODO(b/216639668)
- final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
- service.groupNextActivePreset(groupId, mAttributionSource, recv);
- recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
- } catch (RemoteException | TimeoutException e) {
- Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ service.switchToNextPresetForGroup(groupId, mAttributionSource);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
}
@@ -1066,18 +993,14 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
})
public void switchToPreviousPreset(@NonNull BluetoothDevice device) {
final IBluetoothHapClient service = getService();
- final boolean defaultValue = false;
if (service == null) {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
} else if (isEnabled() && isValidDevice(device)) {
try {
- // TODO(b/216639668)
- final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
- service.previousActivePreset(device, mAttributionSource, recv);
- recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
- } catch (RemoteException | TimeoutException e) {
- Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ service.switchToPreviousPreset(device, mAttributionSource);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
}
@@ -1100,18 +1023,14 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
})
public void switchToPreviousPresetForGroup(int groupId) {
final IBluetoothHapClient service = getService();
- final boolean defaultValue = false;
if (service == null) {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
} else if (isEnabled()) {
try {
- // TODO(b/216639668)
- final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
- service.groupPreviousActivePreset(groupId, mAttributionSource, recv);
- recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
- } catch (RemoteException | TimeoutException e) {
- Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ service.switchToPreviousPresetForGroup(groupId, mAttributionSource);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
}
@@ -1129,24 +1048,26 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED
})
- public @NonNull BluetoothHapPresetInfo getPresetInfo(@NonNull BluetoothDevice device,
+ public @Nullable BluetoothHapPresetInfo getPresetInfo(@NonNull BluetoothDevice device,
int presetIndex) {
final IBluetoothHapClient service = getService();
- final BluetoothHapPresetInfo.Builder builder = new BluetoothHapPresetInfo.Builder();
+ final BluetoothHapPresetInfo defaultValue = null;
if (service == null) {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
} else if (isEnabled() && isValidDevice(device)) {
- // TODO(b/216639668)
- // try {
- // final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
- // service.getPresetInfo(device, presetIndex, mAttributionSource, recv);
- // return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(builder);
- // } catch (RemoteException | TimeoutException e) {
- // Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
- // }
+ try {
+ final SynchronousResultReceiver<BluetoothHapPresetInfo> recv =
+ new SynchronousResultReceiver();
+ service.getPresetInfo(device, presetIndex, mAttributionSource, recv);
+ return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
+ } catch (TimeoutException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
- return builder.build();
+ return defaultValue;
}
/**
@@ -1169,14 +1090,16 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
} else if (isEnabled() && isValidDevice(device)) {
- // TODO(b/216639668)
- // try {
- // final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
- // service.getAllPresetsInfo(device, mAttributionSource, recv);
- // return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
- // } catch (RemoteException | TimeoutException e) {
- // Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
- // }
+ try {
+ final SynchronousResultReceiver<List<BluetoothHapPresetInfo>> recv =
+ new SynchronousResultReceiver();
+ service.getAllPresetInfo(device, mAttributionSource, recv);
+ return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
+ } catch (TimeoutException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
return defaultValue;
}
@@ -1193,19 +1116,21 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED
})
- public boolean getFeatures(@NonNull BluetoothDevice device) {
+ public int getFeatures(@NonNull BluetoothDevice device) {
final IBluetoothHapClient service = getService();
- final boolean defaultValue = false;
+ final int defaultValue = 0x00;
if (service == null) {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
} else if (isEnabled() && isValidDevice(device)) {
try {
- final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
+ final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
service.getFeatures(device, mAttributionSource, recv);
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
- } catch (RemoteException | TimeoutException e) {
+ } catch (TimeoutException e) {
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
return defaultValue;
@@ -1235,18 +1160,14 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
public void setPresetName(@NonNull BluetoothDevice device, int presetIndex,
@NonNull String name) {
final IBluetoothHapClient service = getService();
- final boolean defaultValue = false;
if (service == null) {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
} else if (isEnabled() && isValidDevice(device)) {
try {
- // TODO(b/216639668)
- final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
- service.setPresetName(device, presetIndex, name, mAttributionSource, recv);
- recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
- } catch (RemoteException | TimeoutException e) {
- Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ service.setPresetName(device, presetIndex, name, mAttributionSource);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
}
@@ -1274,18 +1195,14 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
})
public void setPresetNameForGroup(int groupId, int presetIndex, @NonNull String name) {
final IBluetoothHapClient service = getService();
- final boolean defaultValue = false;
if (service == null) {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
} else if (isEnabled()) {
try {
- // TODO(b/216639668)
- final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
- service.groupSetPresetName(groupId, presetIndex, name, mAttributionSource, recv);
- recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
- } catch (RemoteException | TimeoutException e) {
- Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ service.setPresetNameForGroup(groupId, presetIndex, name, mAttributionSource);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
}
diff --git a/framework/java/android/bluetooth/BluetoothHapPresetInfo.java b/framework/java/android/bluetooth/BluetoothHapPresetInfo.java
index b8c09ccbb7..70fb54a3bb 100644
--- a/framework/java/android/bluetooth/BluetoothHapPresetInfo.java
+++ b/framework/java/android/bluetooth/BluetoothHapPresetInfo.java
@@ -29,7 +29,7 @@ import android.os.Parcelable;
@SystemApi
public final class BluetoothHapPresetInfo implements Parcelable {
private int mPresetIndex;
- private String mPresetName;
+ private String mPresetName = "";
private boolean mIsWritable;
private boolean mIsAvailable;
@@ -165,7 +165,7 @@ public final class BluetoothHapPresetInfo implements Parcelable {
* @param isWritable whether preset is writable
* @return the same Builder instance
*/
- public @NonNull Builder setWritable(@NonNull boolean isWritable) {
+ public @NonNull Builder setWritable(boolean isWritable) {
mIsWritable = isWritable;
return this;
}
@@ -176,7 +176,7 @@ public final class BluetoothHapPresetInfo implements Parcelable {
* @param isAvailable whether preset is currently available to select
* @return the same Builder instance
*/
- public @NonNull Builder setAvailable(@NonNull boolean isAvailable) {
+ public @NonNull Builder setAvailable(boolean isAvailable) {
mIsAvailable = isAvailable;
return this;
}
diff --git a/framework/java/android/bluetooth/BluetoothHeadset.java b/framework/java/android/bluetooth/BluetoothHeadset.java
index 8a037a97c0..4ff224d21a 100644
--- a/framework/java/android/bluetooth/BluetoothHeadset.java
+++ b/framework/java/android/bluetooth/BluetoothHeadset.java
@@ -1005,10 +1005,21 @@ public final class BluetoothHeadset implements BluetoothProfile {
BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED,
BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND,
BluetoothStatusCodes.ERROR_TIMEOUT,
+ BluetoothStatusCodes.ERROR_UNKNOWN,
+ })
+ public @interface SetAudioRouteAllowedReturnValues {}
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = {
BluetoothStatusCodes.ALLOWED,
BluetoothStatusCodes.NOT_ALLOWED,
+ BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED,
+ BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND,
+ BluetoothStatusCodes.ERROR_TIMEOUT,
+ BluetoothStatusCodes.ERROR_UNKNOWN,
})
- public @interface AudioRouteAllowedReturnValues {}
+ public @interface GetAudioRouteAllowedReturnValues {}
/**
* Sets whether audio routing is allowed. When set to {@code false}, the AG
@@ -1029,7 +1040,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
})
- public @AudioRouteAllowedReturnValues int setAudioRouteAllowed(boolean allowed) {
+ public @SetAudioRouteAllowedReturnValues int setAudioRouteAllowed(boolean allowed) {
if (VDBG) log("setAudioRouteAllowed");
final IBluetoothHeadset service = mService;
if (service == null) {
@@ -1068,7 +1079,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
})
- public @AudioRouteAllowedReturnValues int getAudioRouteAllowed() {
+ public @GetAudioRouteAllowedReturnValues int getAudioRouteAllowed() {
if (VDBG) log("getAudioRouteAllowed");
final IBluetoothHeadset service = mService;
if (service == null) {
diff --git a/framework/java/android/bluetooth/BluetoothHeadsetClient.java b/framework/java/android/bluetooth/BluetoothHeadsetClient.java
index 87bd76114b..f1402d485d 100644
--- a/framework/java/android/bluetooth/BluetoothHeadsetClient.java
+++ b/framework/java/android/bluetooth/BluetoothHeadsetClient.java
@@ -18,6 +18,7 @@ package android.bluetooth;
import static android.bluetooth.BluetoothUtils.getSyncTimeout;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
@@ -31,6 +32,8 @@ import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.os.RemoteException;
import android.util.CloseGuard;
import android.util.Log;
@@ -1615,6 +1618,218 @@ public final class BluetoothHeadsetClient implements BluetoothProfile, AutoClose
}
return defaultValue;
}
+
+ /**
+ * A class that contains the network service info provided by the HFP Client profile
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final class NetworkServiceState implements Parcelable {
+ /** The device associated with this service state */
+ private final BluetoothDevice mDevice;
+
+ /** True if there is service available, False otherwise */
+ private final boolean mIsServiceAvailable;
+
+ /** The name of the operator associated with the remote device's current network */
+ private final String mOperatorName;
+
+ /**
+ * The general signal strength
+ * (0 - Unknown, 1 - Poor, 2 - Fair, 3 - Good, 4 - Great, 5 - Excellent)
+ */
+ private final int mSignalStrength;
+
+ /** True if we are network roaming, False otherwise */
+ private final boolean mIsRoaming;
+
+ /**
+ * Create a NetworkServiceState Object
+ *
+ * @param device The device associated with this network signal state
+ * @param isServiceAvailable True if there is service available, False otherwise
+ * @param operatorName The name of the operator associated with the remote device's current
+ * network. Use Null if the value is unknown
+ * @param signalStrength The general signal strength
+ * @param isRoaming True if we are network roaming, False otherwise
+ *
+ * @hide
+ */
+ public NetworkServiceState(BluetoothDevice device, boolean isServiceAvailable,
+ String operatorName, int signalStrength, boolean isRoaming) {
+ mDevice = device;
+ mIsServiceAvailable = isServiceAvailable;
+ mOperatorName = operatorName;
+ mSignalStrength = signalStrength;
+ mIsRoaming = isRoaming;
+ }
+
+ /**
+ * Get the device associated with this network service state
+ *
+ * @return a BluetoothDevice associated with this state
+ *
+ * @hide
+ */
+ @SystemApi
+ public @NonNull BluetoothDevice getDevice() {
+ return mDevice;
+ }
+
+ /**
+ * Get the network service availablility state
+ *
+ * @return True if there is service available, False otherwise
+ *
+ * @hide
+ */
+ @SystemApi
+ public boolean isServiceAvailable() {
+ return mIsServiceAvailable;
+ }
+
+ /**
+ * Get the network operator name
+ *
+ * @return A string representing the name of the operator the remote device is on, or null
+ * if unknown.
+ *
+ * @hide
+ */
+ @SystemApi
+ public @Nullable String getOperatorName() {
+ return mOperatorName;
+ }
+
+ /**
+ * Get the network's general signal strength
+ *
+ * @return The general signal strength (0 - None, 1 - Poor, 2 - Fair, 3 - Good,
+ * 4 - Great, 5 - Excellent)
+ *
+ * @hide
+ */
+ @SystemApi
+ public int getSignalStrength() {
+ return mSignalStrength;
+ }
+
+ /**
+ * Get the network service roaming status
+ *
+ * * @return True if we are network roaming, False otherwise
+ *
+ * @hide
+ */
+ @SystemApi
+ public boolean isRoaming() {
+ return mIsRoaming;
+ }
+
+ /**
+ * {@link Parcelable.Creator} interface implementation.
+ */
+ public static final @NonNull Parcelable.Creator<NetworkServiceState> CREATOR =
+ new Parcelable.Creator<NetworkServiceState>() {
+ public NetworkServiceState createFromParcel(Parcel in) {
+ return new NetworkServiceState((BluetoothDevice) in.readParcelable(null),
+ in.readInt() == 1, in.readString(), in.readInt(), in.readInt() == 1);
+ }
+
+ public @NonNull NetworkServiceState[] newArray(int size) {
+ return new NetworkServiceState[size];
+ }
+ };
+
+ /**
+ * @hide
+ */
+ @Override
+ public void writeToParcel(@NonNull Parcel out, int flags) {
+ out.writeParcelable(mDevice, 0);
+ out.writeInt(mIsServiceAvailable ? 1 : 0);
+ out.writeString(mOperatorName);
+ out.writeInt(mSignalStrength);
+ out.writeInt(mIsRoaming ? 1 : 0);
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+ }
+
+ /**
+ * Intent used to broadcast the change in network service state of an HFP Client device
+ *
+ * <p>This intent will have 2 extras:
+ * <ul>
+ * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+ * <li> {@link EXTRA_NETWORK_SERVICE_STATE} - A {@link NetworkServiceState} object. </li>
+ * </ul>
+ *
+ * @hide
+ */
+ @SuppressLint("ActionValue")
+ @SystemApi
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.BLUETOOTH_CONNECT,
+ android.Manifest.permission.BLUETOOTH_PRIVILEGED,
+ })
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_NETWORK_SERVICE_STATE_CHANGED =
+ "android.bluetooth.headsetclient.profile.action.NETWORK_SERVICE_STATE_CHANGED";
+
+ /**
+ * Extra for the network service state changed intent.
+ *
+ * This extra represents the current network service state of a connected Bluetooth device.
+ *
+ * @hide
+ */
+ @SuppressLint("ActionValue")
+ @SystemApi
+ public static final String EXTRA_NETWORK_SERVICE_STATE =
+ "android.bluetooth.headsetclient.extra.EXTRA_NETWORK_SERVICE_STATE";
+
+ /**
+ * Get the network service state for a device
+ *
+ * @param device The {@link BluetoothDevice} you want the network service state for
+ * @return A {@link NetworkServiceState} representing the network service state of the device,
+ * or null if the device is not connected
+ * @hide
+ */
+ @SystemApi
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.BLUETOOTH_CONNECT,
+ android.Manifest.permission.BLUETOOTH_PRIVILEGED,
+ })
+ public @Nullable NetworkServiceState getNetworkServiceState(@NonNull BluetoothDevice device) {
+ if (device == null) {
+ return null;
+ }
+
+ Bundle agEvents = getCurrentAgEvents(device);
+ if (agEvents == null) {
+ return null;
+ }
+
+ boolean isServiceAvailable = (agEvents.getInt(EXTRA_NETWORK_STATUS, 0) == 1);
+ int signalStrength = agEvents.getInt(EXTRA_NETWORK_SIGNAL_STRENGTH, 0);
+ String operatorName = agEvents.getString(EXTRA_OPERATOR_NAME, null);
+ boolean isRoaming = (agEvents.getInt(EXTRA_NETWORK_ROAMING, 0) == 1);
+
+ return new NetworkServiceState(device, isServiceAvailable, operatorName, signalStrength,
+ isRoaming);
+ }
+
private boolean isEnabled() {
return mAdapter.getState() == BluetoothAdapter.STATE_ON;
}
diff --git a/framework/java/android/bluetooth/BluetoothLeAudioCodecConfig.java b/framework/java/android/bluetooth/BluetoothLeAudioCodecConfig.java
index e3f691a66a..8377c2c7d2 100644
--- a/framework/java/android/bluetooth/BluetoothLeAudioCodecConfig.java
+++ b/framework/java/android/bluetooth/BluetoothLeAudioCodecConfig.java
@@ -336,14 +336,14 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
/**
* Returns the frame duration.
*/
- public @ChannelMode int getFrameDuration() {
+ public @FrameDuration int getFrameDuration() {
return mFrameDuration;
}
/**
* Returns the octets per frame
*/
- public @ChannelMode int getOctetsPerFrame() {
+ public int getOctetsPerFrame() {
return mOctetsPerFrame;
}
diff --git a/framework/java/android/bluetooth/BluetoothProfile.java b/framework/java/android/bluetooth/BluetoothProfile.java
index 86606d2077..ff95269c30 100644
--- a/framework/java/android/bluetooth/BluetoothProfile.java
+++ b/framework/java/android/bluetooth/BluetoothProfile.java
@@ -19,7 +19,6 @@ package android.bluetooth;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.RequiresNoPermission;
-import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
@@ -457,7 +456,7 @@ public interface BluetoothProfile {
*/
@SystemApi
@NonNull
- @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
+ @RequiresNoPermission
static String getConnectionStateName(int connectionState) {
switch (connectionState) {
case STATE_DISCONNECTED:
@@ -482,7 +481,7 @@ public interface BluetoothProfile {
*/
@SystemApi
@NonNull
- @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
+ @RequiresNoPermission
static String getProfileName(int profile) {
switch(profile) {
case HEADSET:
diff --git a/framework/java/android/bluetooth/BluetoothStatusCodes.java b/framework/java/android/bluetooth/BluetoothStatusCodes.java
index 8825c3e71b..ebaace621b 100644
--- a/framework/java/android/bluetooth/BluetoothStatusCodes.java
+++ b/framework/java/android/bluetooth/BluetoothStatusCodes.java
@@ -227,7 +227,7 @@ public final class BluetoothStatusCodes {
* @hide
*/
@SystemApi
- public static final int ERROR_REMOTE_OPERATION_NOT_SUPPORTED = 24;
+ public static final int ERROR_REMOTE_OPERATION_NOT_SUPPORTED = 27;
/**
* A GATT writeCharacteristic request is not permitted on the remote device.
diff --git a/framework/java/android/bluetooth/BluetoothUuid.java b/framework/java/android/bluetooth/BluetoothUuid.java
index 7c9a076270..85c16f1288 100644
--- a/framework/java/android/bluetooth/BluetoothUuid.java
+++ b/framework/java/android/bluetooth/BluetoothUuid.java
@@ -158,9 +158,8 @@ public final class BluetoothUuid {
/** @hide */
@NonNull
@SystemApi
- /* FIXME: Not known yet, using a placeholder instead. */
public static final ParcelUuid HAS =
- ParcelUuid.fromString("EEEEEEEE-EEEE-EEEE-EEEE-EEEEEEEEEEEE");
+ ParcelUuid.fromString("00001854-0000-1000-8000-00805F9B34FB");
/** @hide */
@NonNull
@SystemApi
@@ -199,6 +198,11 @@ public final class BluetoothUuid {
/** @hide */
@NonNull
@SystemApi
+ public static final ParcelUuid BASS =
+ ParcelUuid.fromString("0000184F-0000-1000-8000-00805F9B34FB");
+ /** @hide */
+ @NonNull
+ @SystemApi
public static final ParcelUuid BASE_UUID =
ParcelUuid.fromString("00000000-0000-1000-8000-00805F9B34FB");
diff --git a/framework/tests/Android.bp b/framework/tests/Android.bp
index a6a2fe5115..efec1dd521 100644
--- a/framework/tests/Android.bp
+++ b/framework/tests/Android.bp
@@ -4,8 +4,18 @@ package {
android_test {
name: "BluetoothTests",
+
+ defaults: ["framework-bluetooth-tests-defaults"],
+
+ min_sdk_version: "current",
+ target_sdk_version: "current",
+
// Include all test java files.
srcs: ["src/**/*.java"],
+ jacoco: {
+ include_filter: ["android.bluetooth.*"],
+ exclude_filter: [],
+ },
libs: [
"android.test.runner",
"android.test.base",
@@ -14,6 +24,8 @@ android_test {
"junit",
"modules-utils-bytesmatcher",
],
- platform_apis: true,
- certificate: "platform",
+ test_suites: [
+ "general-tests",
+ "mts-bluetooth",
+ ],
}
diff --git a/service/Android.bp b/service/Android.bp
index a0f6ec6dc8..b115b6953c 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -61,10 +61,12 @@ java_library {
libs: [
"framework-annotations-lib",
"framework-bluetooth-pre-jarjar",
+ "app-compat-annotations",
],
static_libs: [
"androidx.annotation_annotation",
+ "androidx.appcompat_appcompat",
],
apex_available: [
@@ -78,22 +80,24 @@ java_library {
name: "service-bluetooth",
defaults: ["service-bluetooth-common-defaults"],
installable: true,
- static_libs: ["service-bluetooth-pre-jarjar"],
+ static_libs: [
+ "service-bluetooth-pre-jarjar",
+ "androidx.appcompat_appcompat",
+ ],
libs: [
"framework-bluetooth.impl",
+ "app-compat-annotations",
],
sdk_version: "system_server_current",
+ jarjar_rules: ":bluetooth-jarjar-rules",
+
optimize: {
enabled: true,
shrink: true,
proguard_flags_files: ["proguard.flags"],
},
- dex_preopt: {
- enabled: false,
- app_image: false,
- },
visibility: [
"//packages/modules/Bluetooth/apex",
],
diff --git a/service/OWNERS b/service/OWNERS
new file mode 100644
index 0000000000..ffb8a05845
--- /dev/null
+++ b/service/OWNERS
@@ -0,0 +1,6 @@
+# Reviewers for /service
+
+rahulsabnis@google.com
+sattiraju@google.com
+siyuanh@google.com
+zachoverflow@google.com \ No newline at end of file
diff --git a/service/java/com/android/server/bluetooth/BluetoothAirplaneModeListener.java b/service/java/com/android/server/bluetooth/BluetoothAirplaneModeListener.java
index 380b1f37b9..d4aad1c642 100644
--- a/service/java/com/android/server/bluetooth/BluetoothAirplaneModeListener.java
+++ b/service/java/com/android/server/bluetooth/BluetoothAirplaneModeListener.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.bluetooth;
import android.annotation.RequiresPermission;
import android.content.Context;
@@ -37,7 +37,7 @@ import com.android.internal.annotations.VisibleForTesting;
* 2. Bluetooth Hearing Aid profile is connected.
* 3. Bluetooth LE Audio is connected
*/
-class BluetoothAirplaneModeListener {
+public class BluetoothAirplaneModeListener {
private static final String TAG = "BluetoothAirplaneModeListener";
@VisibleForTesting static final String TOAST_COUNT = "bluetooth_airplane_toast_count";
diff --git a/service/java/com/android/server/bluetooth/BluetoothDeviceConfigListener.java b/service/java/com/android/server/bluetooth/BluetoothDeviceConfigListener.java
index 49779c0a0c..62860a5f02 100644
--- a/service/java/com/android/server/bluetooth/BluetoothDeviceConfigListener.java
+++ b/service/java/com/android/server/bluetooth/BluetoothDeviceConfigListener.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.bluetooth;
import android.provider.DeviceConfig;
import android.util.Log;
@@ -30,7 +30,7 @@ import java.util.ArrayList;
* 1. Bluetooth A2DP is connected.
* 2. Bluetooth Hearing Aid profile is connected.
*/
-class BluetoothDeviceConfigListener {
+public class BluetoothDeviceConfigListener {
private static final String TAG = "BluetoothDeviceConfigListener";
private final BluetoothManagerService mService;
diff --git a/service/java/com/android/server/bluetooth/BluetoothManagerService.java b/service/java/com/android/server/bluetooth/BluetoothManagerService.java
index 366104a326..f6201a7b3f 100644
--- a/service/java/com/android/server/bluetooth/BluetoothManagerService.java
+++ b/service/java/com/android/server/bluetooth/BluetoothManagerService.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.bluetooth;
import static android.Manifest.permission.BLUETOOTH_CONNECT;
import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
@@ -28,6 +28,8 @@ import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.BroadcastOptions;
+import android.app.admin.DevicePolicyManager;
+import android.app.compat.CompatChanges;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothHearingAid;
@@ -43,7 +45,8 @@ import android.bluetooth.IBluetoothManager;
import android.bluetooth.IBluetoothManagerCallback;
import android.bluetooth.IBluetoothProfileServiceConnection;
import android.bluetooth.IBluetoothStateChangeCallback;
-import android.content.ActivityNotFoundException;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
import android.content.AttributionSource;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -79,11 +82,13 @@ import android.provider.Settings.SettingNotFoundException;
import android.sysprop.BluetoothProperties;
import android.text.TextUtils;
import android.util.Log;
+import android.util.Pair;
import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.modules.utils.SynchronousResultReceiver;
+import com.android.server.BluetoothManagerServiceDumpProto;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
@@ -100,7 +105,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.ReentrantReadWriteLock;
-class BluetoothManagerService extends IBluetoothManager.Stub {
+public class BluetoothManagerService extends IBluetoothManager.Stub {
private static final String TAG = "BluetoothManagerService";
private static final boolean DBG = true;
@@ -178,6 +183,17 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
private static final int SERVICE_IBLUETOOTH = 1;
private static final int SERVICE_IBLUETOOTHGATT = 2;
+ private static final int FLAGS_SYSTEM_APP =
+ ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
+
+ /**
+ * Starting with {@link android.os.Build.VERSION_CODES#TIRAMISU}, applications are
+ * not allowed to enable/disable Bluetooth.
+ */
+ @ChangeId
+ @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.TIRAMISU)
+ static final long RESTRICT_ENABLE_DISABLE = 218493289L;
+
private final Context mContext;
private final UserManager mUserManager;
@@ -275,8 +291,6 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
// bluetooth profile services
private final Map<Integer, ProfileServiceConnections> mProfileServices = new HashMap<>();
- private final boolean mWirelessConsentRequired;
-
private final IBluetoothCallback mBluetoothCallback = new IBluetoothCallback.Stub() {
@Override
public void onBluetoothStateChange(int prevState, int newState) throws RemoteException {
@@ -488,10 +502,6 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
mContext = context;
- mWirelessConsentRequired = context.getResources()
- .getBoolean(Resources.getSystem().getIdentifier(
- "config_wirelessConsentRequired", "bool", "android"));
-
mCrashes = 0;
mBluetooth = null;
mBluetoothBinder = null;
@@ -1282,10 +1292,10 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
}
final int callingUid = Binder.getCallingUid();
- final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
- if (!callerSystem && !isEnabled() && mWirelessConsentRequired
- && startConsentUiIfNeeded(packageName,
- callingUid, BluetoothAdapter.ACTION_REQUEST_ENABLE)) {
+ final int callingPid = Binder.getCallingPid();
+ if (!isPrivileged(callingPid, callingUid) && !isDeviceOwner(callingUid, packageName)
+ && CompatChanges.isChangeEnabled(RESTRICT_ENABLE_DISABLE, callingUid)
+ && !isSystem(packageName, callingUid)) {
return false;
}
@@ -1324,10 +1334,10 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
}
final int callingUid = Binder.getCallingUid();
- final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
- if (!callerSystem && isEnabled() && mWirelessConsentRequired
- && startConsentUiIfNeeded(packageName,
- callingUid, BluetoothAdapter.ACTION_REQUEST_DISABLE)) {
+ final int callingPid = Binder.getCallingPid();
+ if (!isPrivileged(callingPid, callingUid) && !isDeviceOwner(callingUid, packageName)
+ && CompatChanges.isChangeEnabled(RESTRICT_ENABLE_DISABLE, callingUid)
+ && !isSystem(packageName, callingUid)) {
return false;
}
@@ -1374,39 +1384,6 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
return true;
}
- private boolean startConsentUiIfNeeded(String packageName,
- int callingUid, String intentAction) throws RemoteException {
- if (checkBluetoothPermissionWhenWirelessConsentRequired()) {
- return false;
- }
- try {
- // Validate the package only if we are going to use it
- ApplicationInfo applicationInfo = mContext.getPackageManager()
- .getApplicationInfoAsUser(packageName,
- PackageManager.MATCH_DIRECT_BOOT_AUTO,
- UserHandle.getUserHandleForUid(callingUid));
- if (applicationInfo.uid != callingUid) {
- throw new SecurityException("Package " + packageName
- + " not in uid " + callingUid);
- }
-
- Intent intent = new Intent(intentAction);
- intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
- intent.setFlags(
- Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
- try {
- mContext.startActivity(intent);
- } catch (ActivityNotFoundException e) {
- // Shouldn't happen
- Log.e(TAG, "Intent to handle action " + intentAction + " missing");
- return false;
- }
- return true;
- } catch (PackageManager.NameNotFoundException e) {
- throw new RemoteException(e.getMessage());
- }
- }
-
/**
* Check if AppOpsManager is available and the packageName belongs to uid
*
@@ -3528,4 +3505,60 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
}
return comp;
}
+
+ private boolean isPrivileged(int pid, int uid) {
+ return (mContext.checkPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED, pid, uid)
+ == PackageManager.PERMISSION_GRANTED)
+ || (mContext.checkPermission(android.Manifest.permission.NETWORK_SETTINGS, pid, uid)
+ == PackageManager.PERMISSION_GRANTED)
+ || (mContext.getPackageManager().checkSignatures(uid, Process.SYSTEM_UID)
+ == PackageManager.SIGNATURE_MATCH);
+ }
+
+ private Pair<UserHandle, ComponentName> getDeviceOwner() {
+ DevicePolicyManager devicePolicyManager =
+ mContext.getSystemService(DevicePolicyManager.class);
+ if (devicePolicyManager == null) return null;
+ long ident = Binder.clearCallingIdentity();
+ UserHandle deviceOwnerUser = null;
+ ComponentName deviceOwnerComponent = null;
+ try {
+ deviceOwnerUser = devicePolicyManager.getDeviceOwnerUser();
+ deviceOwnerComponent = devicePolicyManager.getDeviceOwnerComponentOnAnyUser();
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ if (deviceOwnerUser == null || deviceOwnerComponent == null
+ || deviceOwnerComponent.getPackageName() == null) {
+ return null;
+ }
+ return new Pair<>(deviceOwnerUser, deviceOwnerComponent);
+ }
+
+ private boolean isDeviceOwner(int uid, String packageName) {
+ if (packageName == null) {
+ Log.e(TAG, "isDeviceOwner: packageName is null, returning false");
+ return false;
+ }
+ Pair<UserHandle, ComponentName> deviceOwner = getDeviceOwner();
+
+ // no device owner
+ if (deviceOwner == null) return false;
+
+ return deviceOwner.first.equals(UserHandle.getUserHandleForUid(uid))
+ && deviceOwner.second.getPackageName().equals(packageName);
+ }
+
+ public boolean isSystem(String packageName, int uid) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ ApplicationInfo info = mContext.getPackageManager().getApplicationInfoAsUser(
+ packageName, 0, UserHandle.getUserHandleForUid(uid));
+ return (info.flags & FLAGS_SYSTEM_APP) != 0;
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
}
diff --git a/service/java/com/android/server/bluetooth/BluetoothModeChangeHelper.java b/service/java/com/android/server/bluetooth/BluetoothModeChangeHelper.java
index fd728ad494..dbdc466ad9 100644
--- a/service/java/com/android/server/bluetooth/BluetoothModeChangeHelper.java
+++ b/service/java/com/android/server/bluetooth/BluetoothModeChangeHelper.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.bluetooth;
import android.annotation.RequiresPermission;
import android.bluetooth.BluetoothA2dp;
diff --git a/service/java/com/android/server/bluetooth/BluetoothService.java b/service/java/com/android/server/bluetooth/BluetoothService.java
index f5e100b338..ff6938e5f6 100644
--- a/service/java/com/android/server/bluetooth/BluetoothService.java
+++ b/service/java/com/android/server/bluetooth/BluetoothService.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.bluetooth;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -22,9 +22,10 @@ import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.os.UserManager;
+import com.android.server.SystemService;
import com.android.server.SystemService.TargetUser;
-class BluetoothService extends SystemService {
+public class BluetoothService extends SystemService {
private BluetoothManagerService mBluetoothManagerService;
private boolean mInitialized = false;
diff --git a/service/tests/Android.bp b/service/tests/Android.bp
index 6cfa7ecb63..2f889aa797 100644
--- a/service/tests/Android.bp
+++ b/service/tests/Android.bp
@@ -28,3 +28,54 @@ filegroup {
"//frameworks/base/services/tests/servicestests",
],
}
+
+android_test {
+ name: "ServiceBluetoothTests",
+
+ srcs: [
+ "src/**/*.java",
+ ],
+
+ dxflags: ["--multi-dex"],
+
+ java_version: "1.9",
+
+ static_libs: [
+ "androidx.test.rules",
+ "collector-device-lib",
+ "hamcrest-library",
+ "mockito-target-extended-minus-junit4",
+ "platform-test-annotations",
+ "frameworks-base-testutils",
+ "truth-prebuilt",
+
+ // Statically link service-bluetooth-pre-jarjar since we want to test the working copy of
+ // service-uwb, not the on-device copy.
+ // Use pre-jarjar version so that we can reference symbols before they are renamed.
+ // Then, the jarjar_rules here will perform the rename for the entire APK
+ // i.e. service-bluetooth + test code
+ "service-bluetooth-pre-jarjar",
+ ],
+
+ jarjar_rules: ":bluetooth-jarjar-rules",
+
+ libs: [
+ "android.test.runner",
+ "android.test.base",
+ "android.test.mock",
+ "framework-bluetooth-pre-jarjar",
+ ],
+
+ jni_libs: [
+ // these are needed for Extended Mockito
+ "//packages/modules/Bluetooth/android/app:libbluetooth_jni",
+ ],
+ compile_multilib: "both",
+
+ min_sdk_version: "current",
+
+ test_suites: [
+ "general-tests",
+ "mts-bluetooth",
+ ],
+}
diff --git a/service/tests/AndroidManifest.xml b/service/tests/AndroidManifest.xml
new file mode 100644
index 0000000000..afecc067ed
--- /dev/null
+++ b/service/tests/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 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
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.server.bluetooth.test">
+
+ <application android:debuggable="true"
+ android:largeHeap="true">
+ <uses-library android:name="android.test.runner"/>
+ <activity android:label="BluetoothTestDummyLabel"
+ android:name="BluetoothTestDummyName"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
+ </application>
+
+ <instrumentation android:name="com.android.server.bluetooth.CustomTestRunner"
+ android:targetPackage="com.android.server.bluetooth.test"
+ android:label="Service Bluetooth Tests">
+ </instrumentation>
+
+ <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
+ <uses-permission android:name="android.permission.INTERNET"/>
+
+</manifest>
diff --git a/service/tests/AndroidTest.xml b/service/tests/AndroidTest.xml
new file mode 100644
index 0000000000..c31c6cb068
--- /dev/null
+++ b/service/tests/AndroidTest.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Runs Service Bluetooth Tests.">
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="test-file-name" value="ServiceBluetoothTests.apk" />
+ </target_preparer>
+
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-tag" value="ServiceBluetoothTests" />
+ <option name="config-descriptor:metadata" key="mainline-param"
+ value="com.google.android.bluetooth.apex" />
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="com.android.server.bluetooth.test" />
+ <option name="runner" value="com.android.server.bluetooth.CustomTestRunner" />
+ <option name="hidden-api-checks" value="false"/>
+ </test>
+
+ <!-- Only run ServiceBluetoothTests in MTS if the Bluetooth Mainline module is installed. -->
+ <object type="module_controller"
+ class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
+ <option name="mainline-module-package-name" value="com.google.android.bluetooth" />
+ </object>
+</configuration>
diff --git a/service/tests/src/com/android/server/BluetoothAirplaneModeListenerTest.java b/service/tests/src/com/android/server/BluetoothAirplaneModeListenerTest.java
index a1d4c203de..fb067800a1 100644
--- a/service/tests/src/com/android/server/BluetoothAirplaneModeListenerTest.java
+++ b/service/tests/src/com/android/server/BluetoothAirplaneModeListenerTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.bluetooth;
import static org.mockito.Mockito.*;
diff --git a/system/Android.bp b/system/Android.bp
index 6b06881f7b..f3bbab694e 100644
--- a/system/Android.bp
+++ b/system/Android.bp
@@ -1,3 +1,15 @@
+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
+ // SPDX-license-identifier-BSD
+ // SPDX-license-identifier-MIT
+ // legacy_unencumbered
+ default_applicable_licenses: ["system_bt_license"],
+}
+
filegroup {
name: "BlueberryFacadeProto",
srcs: [
@@ -164,10 +176,10 @@ genrule {
"protoc-gen-grpc-python-plugin",
"soong_zip",
],
- cmd: "$(location aprotoc) --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-python-plugin) -Ipackages/modules/Bluetooth/system $(in) --grpc_out=$(genDir) --python_out=$(genDir)",
+ cmd: "$(location aprotoc) --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-python-plugin) -Iexternal/protobuf/src -Ipackages/modules/Bluetooth/system $(in) --grpc_out=$(genDir) --python_out=$(genDir)",
srcs: ["blueberry/facade/topshim/facade.proto"],
out: [
"blueberry/facade/topshim/facade_pb2.py",
"blueberry/facade/topshim/facade_pb2_grpc.py"
],
-} \ No newline at end of file
+}
diff --git a/system/OWNERS b/system/OWNERS
new file mode 100644
index 0000000000..ab51efd928
--- /dev/null
+++ b/system/OWNERS
@@ -0,0 +1,13 @@
+# Reviewers for /system
+
+cmanton@google.com
+cncn@google.com
+hsz@google.com
+jpawlowski@google.com
+mylesgw@google.com
+optedoblivion@google.com
+qasimj@google.com
+rahulsabnis@google.com
+sattiraju@google.com
+siyuanh@google.com
+zachoverflow@google.com
diff --git a/system/audio_bluetooth_hw/Android.bp b/system/audio_bluetooth_hw/Android.bp
index 08496c22a1..25e1f8c141 100644
--- a/system/audio_bluetooth_hw/Android.bp
+++ b/system/audio_bluetooth_hw/Android.bp
@@ -17,21 +17,25 @@ cc_library_shared {
"audio_bluetooth_hw.cc",
"stream_apis.cc",
"device_port_proxy.cc",
+ "device_port_proxy_hidl.cc",
"utils.cc",
],
header_libs: ["libhardware_headers"],
shared_libs: [
- "android.hardware.bluetooth.audio@2.0",
- "android.hardware.bluetooth.audio@2.1",
- "android.hardware.bluetooth.audio@2.2",
+ "android.hardware.bluetooth.audio-V1-ndk",
+ "libbluetooth_audio_session_aidl",
"libaudioutils",
"libbase",
- "libbluetooth_audio_session",
+ "libbinder_ndk",
"libcutils",
"libfmq",
- "libhidlbase",
"liblog",
"libutils",
+ // HIDL dependencies
+ "android.hardware.bluetooth.audio@2.0",
+ "android.hardware.bluetooth.audio@2.1",
+ "libbluetooth_audio_session",
+ "libhidlbase",
],
cflags: [
"-Wall",
diff --git a/system/audio_bluetooth_hw/device_port_proxy.cc b/system/audio_bluetooth_hw/device_port_proxy.cc
index ed9f0952ba..b9be63de36 100644
--- a/system/audio_bluetooth_hw/device_port_proxy.cc
+++ b/system/audio_bluetooth_hw/device_port_proxy.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright 2022 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.
@@ -14,7 +14,9 @@
* limitations under the License.
*/
-#define LOG_TAG "BTAudioHalDeviceProxy"
+#define LOG_TAG "BTAudioHalDeviceProxyAIDL"
+
+#include "device_port_proxy.h"
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
@@ -23,56 +25,29 @@
#include <log/log.h>
#include <stdlib.h>
-#include "BluetoothAudioSessionControl_2_2.h"
-#include "device_port_proxy.h"
+#include "BluetoothAudioSessionControl.h"
#include "stream_apis.h"
#include "utils.h"
namespace android {
namespace bluetooth {
namespace audio {
+namespace aidl {
+
+using ::aidl::android::hardware::bluetooth::audio::AudioConfiguration;
+using ::aidl::android::hardware::bluetooth::audio::BluetoothAudioSessionControl;
+using ::aidl::android::hardware::bluetooth::audio::ChannelMode;
+using ::aidl::android::hardware::bluetooth::audio::PcmConfiguration;
+using ::aidl::android::hardware::bluetooth::audio::PortStatusCallbacks;
+using ::aidl::android::hardware::bluetooth::audio::PresentationPosition;
using ::android::base::StringPrintf;
-using ::android::bluetooth::audio::BluetoothAudioSessionControl_2_2;
-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:
@@ -95,13 +70,13 @@ audio_channel_mask_t InputChannelModeToAudioFormat(ChannelMode channel_mode) {
}
}
-audio_format_t BitsPerSampleToAudioFormat(BitsPerSample bits_per_sample) {
+audio_format_t BitsPerSampleToAudioFormat(uint8_t bits_per_sample) {
switch (bits_per_sample) {
- case BitsPerSample::BITS_16:
+ case 16:
return AUDIO_FORMAT_PCM_16_BIT;
- case BitsPerSample::BITS_24:
+ case 24:
return AUDIO_FORMAT_PCM_24_BIT_PACKED;
- case BitsPerSample::BITS_32:
+ case 32:
return AUDIO_FORMAT_PCM_32_BIT;
default:
return kBluetoothDefaultAudioFormatBitsPerSample;
@@ -113,12 +88,21 @@ constexpr unsigned int kMaxWaitingTimeMs = 4500;
} // namespace
-BluetoothAudioPort::BluetoothAudioPort()
- : cookie_(android::bluetooth::audio::kObserversCookieUndefined),
+BluetoothAudioPortAidl::BluetoothAudioPortAidl()
+ : cookie_(::aidl::android::hardware::bluetooth::audio::
+ kObserversCookieUndefined),
state_(BluetoothStreamState::DISABLED),
- session_type_(SessionType_2_1::UNKNOWN) {}
+ session_type_(SessionType::UNKNOWN) {}
-bool BluetoothAudioPort::SetUp(audio_devices_t devices) {
+BluetoothAudioPortAidlOut::~BluetoothAudioPortAidlOut() {
+ if (in_use()) TearDown();
+}
+
+BluetoothAudioPortAidlIn::~BluetoothAudioPortAidlIn() {
+ if (in_use()) TearDown();
+}
+
+bool BluetoothAudioPortAidl::SetUp(audio_devices_t devices) {
if (!init_session_type(devices)) return false;
state_ = BluetoothStreamState::STANDBY;
@@ -126,106 +110,120 @@ bool BluetoothAudioPort::SetUp(audio_devices_t devices) {
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";
+ LOG(ERROR) << "control_result_cb: BluetoothAudioPortAidl is not in use";
return;
}
if (port->cookie_ != cookie) {
- LOG(ERROR) << "control_result_cb: proxy of device port (cookie=" << StringPrintf("%#hx", cookie)
- << ") is corrupted";
+ 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";
+ LOG(ERROR) << "session_changed_cb: BluetoothAudioPortAidl is not in use";
return;
}
if (port->cookie_ != cookie) {
- LOG(ERROR) << "session_changed_cb: proxy of device port (cookie=" << StringPrintf("%#hx", cookie)
- << ") is corrupted";
+ LOG(ERROR) << "session_changed_cb: proxy of device port (cookie="
+ << StringPrintf("%#hx", cookie) << ") is corrupted";
return;
}
port->SessionChangedHandler();
};
- ::android::bluetooth::audio::PortStatusCallbacks cbacks = {
+ // TODO: Add audio_config_changed_cb
+ PortStatusCallbacks cbacks = {
.control_result_cb_ = control_result_cb,
- .session_changed_cb_ = session_changed_cb};
- cookie_ = BluetoothAudioSessionControl_2_2::RegisterControlResultCback(
+ .session_changed_cb_ = session_changed_cb,
+ };
+ cookie_ = BluetoothAudioSessionControl::RegisterControlResultCback(
session_type_, cbacks);
- LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_);
+ LOG(INFO) << __func__ << ": session_type=" << toString(session_type_)
+ << ", cookie=" << StringPrintf("%#hx", cookie_);
- return (cookie_ != android::bluetooth::audio::kObserversCookieUndefined);
+ return (
+ cookie_ !=
+ ::aidl::android::hardware::bluetooth::audio::kObserversCookieUndefined);
}
-bool BluetoothAudioPort::init_session_type(audio_devices_t device) {
+bool BluetoothAudioPortAidl::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;
+ LOG(VERBOSE)
+ << __func__
+ << ": device=AUDIO_DEVICE_OUT_BLUETOOTH_A2DP (HEADPHONES/SPEAKER) ("
+ << StringPrintf("%#x", device) << ")";
+ session_type_ = SessionType::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;
+ LOG(VERBOSE) << __func__
+ << ": device=AUDIO_DEVICE_OUT_HEARING_AID (MEDIA/VOICE) ("
+ << StringPrintf("%#x", device) << ")";
+ session_type_ = SessionType::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;
+ session_type_ = SessionType::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;
+ session_type_ = SessionType::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;
+ session_type_ = SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH;
break;
default:
- LOG(ERROR) << __func__ << ": unknown device=" << StringPrintf("%#x", device);
+ LOG(ERROR) << __func__
+ << ": unknown device=" << StringPrintf("%#x", device);
return false;
}
- if (!BluetoothAudioSessionControl_2_2::IsSessionReady(session_type_)) {
- LOG(ERROR) << __func__ << ": device=" << StringPrintf("%#x", device) << ", session_type=" << toString(session_type_)
+ if (!BluetoothAudioSessionControl::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() {
+void BluetoothAudioPortAidl::TearDown() {
if (!in_use()) {
LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << " unknown monitor";
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
+ << " unknown monitor";
return;
}
- LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_);
- BluetoothAudioSessionControl_2_2::UnregisterControlResultCback(session_type_,
- cookie_);
- cookie_ = android::bluetooth::audio::kObserversCookieUndefined;
+ LOG(INFO) << __func__ << ": session_type=" << toString(session_type_)
+ << ", cookie=" << StringPrintf("%#hx", cookie_);
+ BluetoothAudioSessionControl::UnregisterControlResultCback(session_type_,
+ cookie_);
+ cookie_ =
+ ::aidl::android::hardware::bluetooth::audio::kObserversCookieUndefined;
}
-void BluetoothAudioPort::ControlResultHandler(
+void BluetoothAudioPortAidl::ControlResultHandler(
const BluetoothAudioStatus& status) {
if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPortis not in use";
+ LOG(ERROR) << __func__ << ": BluetoothAudioPortAidlis 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
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
+ << ", previous_state=" << previous_state
<< ", status=" << toString(status);
switch (previous_state) {
@@ -236,7 +234,8 @@ void BluetoothAudioPort::ControlResultHandler(
// 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;
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
+ << ", previous_state=" << previous_state;
state_ = BluetoothStreamState::STANDBY;
}
break;
@@ -248,13 +247,15 @@ void BluetoothAudioPort::ControlResultHandler(
// 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;
+ << ", 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_)
+ << " for session_type=" << toString(session_type_)
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
<< ", previous_state=" << previous_state;
return;
}
@@ -262,75 +263,73 @@ void BluetoothAudioPort::ControlResultHandler(
internal_cv_.notify_all();
}
-void BluetoothAudioPort::SessionChangedHandler() {
+void BluetoothAudioPortAidl::SessionChangedHandler() {
if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use";
+ LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl 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;
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
+ << ", previous_state=" << previous_state;
state_ = BluetoothStreamState::DISABLED;
port_lock.unlock();
internal_cv_.notify_all();
}
-bool BluetoothAudioPort::in_use() const {
- return (cookie_ != android::bluetooth::audio::kObserversCookieUndefined);
+bool BluetoothAudioPortAidl::in_use() const {
+ return (
+ cookie_ !=
+ ::aidl::android::hardware::bluetooth::audio::kObserversCookieUndefined);
}
-bool BluetoothAudioPort::GetPreferredDataIntervalUs(size_t* interval_us) const {
+bool BluetoothAudioPortAidl::GetPreferredDataIntervalUs(
+ size_t* interval_us) const {
if (!in_use()) {
return false;
}
- const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration&
- hal_audio_cfg =
- BluetoothAudioSessionControl_2_2::GetAudioConfig(session_type_);
- if (hal_audio_cfg.getDiscriminator() !=
- ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration::
- hidl_discriminator::pcmConfig) {
+ const AudioConfiguration& hal_audio_cfg =
+ BluetoothAudioSessionControl::GetAudioConfig(session_type_);
+ if (hal_audio_cfg.getTag() != AudioConfiguration::pcmConfig) {
return false;
}
- const ::android::hardware::bluetooth::audio::V2_1::PcmParameters& pcm_cfg =
- hal_audio_cfg.pcmConfig();
+ const PcmConfiguration& pcm_cfg =
+ hal_audio_cfg.get<AudioConfiguration::pcmConfig>();
*interval_us = pcm_cfg.dataIntervalUs;
return true;
}
-bool BluetoothAudioPortOut::LoadAudioConfig(audio_config_t* audio_cfg) const {
+bool BluetoothAudioPortAidlOut::LoadAudioConfig(
+ audio_config_t* audio_cfg) const {
if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPortOut is not in use";
+ LOG(ERROR) << __func__ << ": BluetoothAudioPortAidlOut 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_2::AudioConfiguration&
- hal_audio_cfg =
- BluetoothAudioSessionControl_2_2::GetAudioConfig(session_type_);
- if (hal_audio_cfg.getDiscriminator() !=
- ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration::
- hidl_discriminator::pcmConfig) {
+ const AudioConfiguration& hal_audio_cfg =
+ BluetoothAudioSessionControl::GetAudioConfig(session_type_);
+ if (hal_audio_cfg.getTag() != AudioConfiguration::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();
+ const PcmConfiguration& pcm_cfg =
+ hal_audio_cfg.get<AudioConfiguration::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) {
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
+ << ", state=" << state_ << ", PcmConfig=[" << pcm_cfg.toString()
+ << "]";
+ if (pcm_cfg.channelMode == ChannelMode::UNKNOWN) {
return false;
}
- audio_cfg->sample_rate = SampleRateToAudioFormat(pcm_cfg.sampleRate);
+ audio_cfg->sample_rate = pcm_cfg.sampleRateHz;
audio_cfg->channel_mask =
(is_stereo_to_mono_
? AUDIO_CHANNEL_OUT_STEREO
@@ -339,51 +338,48 @@ bool BluetoothAudioPortOut::LoadAudioConfig(audio_config_t* audio_cfg) const {
return true;
}
-bool BluetoothAudioPortIn::LoadAudioConfig(audio_config_t* audio_cfg) const {
+bool BluetoothAudioPortAidlIn::LoadAudioConfig(
+ audio_config_t* audio_cfg) const {
if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPortIn is not in use";
+ LOG(ERROR) << __func__ << ": BluetoothAudioPortAidlIn 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_2::AudioConfiguration&
- hal_audio_cfg =
- BluetoothAudioSessionControl_2_2::GetAudioConfig(session_type_);
- if (hal_audio_cfg.getDiscriminator() !=
- ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration::
- hidl_discriminator::pcmConfig) {
+ const AudioConfiguration& hal_audio_cfg =
+ BluetoothAudioSessionControl::GetAudioConfig(session_type_);
+ if (hal_audio_cfg.getTag() != AudioConfiguration::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();
+ const PcmConfiguration& pcm_cfg =
+ hal_audio_cfg.get<AudioConfiguration::pcmConfig>();
LOG(VERBOSE) << __func__ << ": session_type=" << toString(session_type_)
<< ", cookie=" << StringPrintf("%#hx", cookie_)
- << ", state=" << state_ << ", PcmConfig=[" << toString(pcm_cfg)
+ << ", state=" << state_ << ", PcmConfig=[" << pcm_cfg.toString()
<< "]";
- if (pcm_cfg.sampleRate == SampleRate_2_1::RATE_UNKNOWN ||
- pcm_cfg.channelMode == ChannelMode::UNKNOWN ||
- pcm_cfg.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
+ if (pcm_cfg.channelMode == ChannelMode::UNKNOWN) {
return false;
}
- audio_cfg->sample_rate = SampleRateToAudioFormat(pcm_cfg.sampleRate);
+ audio_cfg->sample_rate = pcm_cfg.sampleRateHz;
audio_cfg->channel_mask = InputChannelModeToAudioFormat(pcm_cfg.channelMode);
audio_cfg->format = BitsPerSampleToAudioFormat(pcm_cfg.bitsPerSample);
return true;
}
-bool BluetoothAudioPort::CondwaitState(BluetoothStreamState state) {
+bool BluetoothAudioPortAidl::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";
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
+ << " waiting for STARTED";
retval = internal_cv_.wait_for(
port_lock, std::chrono::milliseconds(kMaxWaitingTimeMs),
[this] { return this->state_ != BluetoothStreamState::STARTING; });
@@ -391,7 +387,8 @@ bool BluetoothAudioPort::CondwaitState(BluetoothStreamState state) {
break;
case BluetoothStreamState::SUSPENDING:
LOG(VERBOSE) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << " waiting for SUSPENDED";
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
+ << " waiting for SUSPENDED";
retval = internal_cv_.wait_for(
port_lock, std::chrono::milliseconds(kMaxWaitingTimeMs),
[this] { return this->state_ != BluetoothStreamState::SUSPENDING; });
@@ -399,92 +396,107 @@ bool BluetoothAudioPort::CondwaitState(BluetoothStreamState state) {
break;
default:
LOG(WARNING) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << " waiting for KNOWN";
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
+ << " waiting for KNOWN";
return false;
}
return retval; // false if any failure like timeout
}
-bool BluetoothAudioPort::Start() {
+bool BluetoothAudioPortAidl::Start() {
if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use";
+ LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl 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";
+ 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_2::StartStream(session_type_)) {
+ if (BluetoothAudioSessionControl::StartStream(session_type_)) {
retval = CondwaitState(BluetoothStreamState::STARTING);
} else {
LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_ << " Hal fails";
+ << ", 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";
+ << ", 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";
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
+ << ", state=" << state_ << " failure";
}
return retval; // false if any failure like timeout
}
-bool BluetoothAudioPort::Suspend() {
+bool BluetoothAudioPortAidl::Suspend() {
if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use";
+ LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use";
return false;
}
- LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_)
+ 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_2::SuspendStream(session_type_)) {
+ if (BluetoothAudioSessionControl::SuspendStream(session_type_)) {
retval = CondwaitState(BluetoothStreamState::SUSPENDING);
} else {
LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_ << " Hal fails";
+ << ", 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";
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
+ << ", state=" << state_ << " done";
} else {
LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_ << " failure";
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
+ << ", state=" << state_ << " failure";
}
return retval; // false if any failure like timeout
}
-void BluetoothAudioPort::Stop() {
+void BluetoothAudioPortAidl::Stop() {
if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use";
+ LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use";
return;
}
- LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_)
+ LOG(INFO) << __func__ << ": session_type=" << toString(session_type_)
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
<< ", state=" << state_ << " request";
state_ = BluetoothStreamState::DISABLED;
- BluetoothAudioSessionControl_2_2::StopStream(session_type_);
- LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_)
+ BluetoothAudioSessionControl::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 {
+size_t BluetoothAudioPortAidlOut::WriteData(const void* buffer,
+ size_t bytes) const {
if (!in_use()) return 0;
if (!is_stereo_to_mono_) {
- return BluetoothAudioSessionControl_2_2::OutWritePcmData(session_type_,
- buffer, bytes);
+ return BluetoothAudioSessionControl::OutWritePcmData(session_type_, buffer,
+ bytes);
}
// WAR to mix the stereo into Mono (16 bits per sample)
@@ -494,51 +506,62 @@ size_t BluetoothAudioPortOut::WriteData(const void* buffer, size_t bytes) const
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_2::OutWritePcmData(
- session_type_, dst.get(), write_frames * 2) *
+ return BluetoothAudioSessionControl::OutWritePcmData(session_type_, dst.get(),
+ write_frames * 2) *
2;
}
-size_t BluetoothAudioPortIn::ReadData(void* buffer, size_t bytes) const {
+size_t BluetoothAudioPortAidlIn::ReadData(void* buffer, size_t bytes) const {
if (!in_use()) return 0;
- return BluetoothAudioSessionControl_2_2::InReadPcmData(session_type_, buffer,
- bytes);
+ return BluetoothAudioSessionControl::InReadPcmData(session_type_, buffer,
+ bytes);
}
-bool BluetoothAudioPort::GetPresentationPosition(uint64_t* delay_ns,
- uint64_t* bytes,
- timespec* timestamp) const {
+bool BluetoothAudioPortAidl::GetPresentationPosition(
+ uint64_t* delay_ns, uint64_t* bytes, timespec* timestamp) const {
if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use";
+ LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use";
return false;
}
- bool retval = BluetoothAudioSessionControl_2_2::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 << "."
+ PresentationPosition presentation_position;
+ bool retval = BluetoothAudioSessionControl::GetPresentationPosition(
+ session_type_, presentation_position);
+ *delay_ns = presentation_position.remoteDeviceAudioDelayNanos;
+ *bytes = presentation_position.transmittedOctets;
+ *timestamp = {.tv_sec = static_cast<__kernel_old_time_t>(
+ presentation_position.transmittedOctetsTimestamp.tvSec),
+ .tv_nsec = static_cast<long>(
+ presentation_position.transmittedOctetsTimestamp.tvNSec)};
+ 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(
+void BluetoothAudioPortAidl::UpdateSourceMetadata(
const source_metadata* source_metadata) const {
if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use";
+ LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl 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)";
+ 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_2::UpdateTracksMetadata(session_type_,
- source_metadata);
+ BluetoothAudioSessionControl::UpdateSourceMetadata(session_type_,
+ *source_metadata);
}
-void BluetoothAudioPort::UpdateSinkMetadata(
+void BluetoothAudioPortAidl::UpdateSinkMetadata(
const sink_metadata* sink_metadata) const {
if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use";
+ LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use";
return;
}
LOG(DEBUG) << __func__ << ": session_type=" << toString(session_type_)
@@ -546,16 +569,17 @@ void BluetoothAudioPort::UpdateSinkMetadata(
<< ", state=" << state_ << ", " << sink_metadata->track_count
<< " track(s)";
if (sink_metadata->track_count == 0) return;
- BluetoothAudioSessionControl_2_2::UpdateSinkMetadata(session_type_,
- sink_metadata);
+ BluetoothAudioSessionControl::UpdateSinkMetadata(session_type_,
+ *sink_metadata);
}
-BluetoothStreamState BluetoothAudioPort::GetState() const { return state_; }
+BluetoothStreamState BluetoothAudioPortAidl::GetState() const { return state_; }
-void BluetoothAudioPort::SetState(BluetoothStreamState state) {
+void BluetoothAudioPortAidl::SetState(BluetoothStreamState state) {
state_ = state;
}
+} // namespace aidl
} // namespace audio
} // namespace bluetooth
-} // namespace android
+} // namespace android \ No newline at end of file
diff --git a/system/audio_bluetooth_hw/device_port_proxy.h b/system/audio_bluetooth_hw/device_port_proxy.h
index cc5342d50f..dab4970ca6 100644
--- a/system/audio_bluetooth_hw/device_port_proxy.h
+++ b/system/audio_bluetooth_hw/device_port_proxy.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright 2022 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.
@@ -16,8 +16,10 @@
#pragma once
-#include <android/hardware/bluetooth/audio/2.2/types.h>
+#include <aidl/android/hardware/bluetooth/audio/BluetoothAudioStatus.h>
+#include <aidl/android/hardware/bluetooth/audio/SessionType.h>
#include <hardware/audio.h>
+
#include <condition_variable>
#include <mutex>
#include <unordered_map>
@@ -28,112 +30,184 @@ 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.
+/***
+ * 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();
+ 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);
+ /***
+ * 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
+ ***/
+ virtual bool SetUp(audio_devices_t) { return false; }
+
+ /***
+ * Unregister this BluetoothAudioPort from BluetoothAudioSessionControl.
+ * Audio HAL must delete this BluetoothAudioPort after calling this.
+ ***/
+ virtual 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*) const { return false; };
+
+ /***
+ * WAR to support Mono mode / 16 bits per sample
+ ***/
+ virtual void ForcePcmStereoToMono(bool) {}
+
+ /***
+ * 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 true when there are no errors.
+ * Called by Audio framework / HAL to start the stream
+ ***/
+ virtual bool Start() { return false; }
+
+ /***
+ * Called by Audio framework / HAL to suspend the stream
+ ***/
+ virtual bool Suspend() { return false; };
+
+ /***
+ virtual bool Suspend() { return false; }
+ * Called by Audio framework / HAL to stop the stream
+ ***/
+ virtual void Stop() {}
+
+ /***
+ * Called by the Audio framework / HAL to fetch information about audio frames
+ * presented to an external sink, or frames presented fror an internal sink
+ ***/
+ virtual bool GetPresentationPosition(uint64_t*, uint64_t*, timespec*) const {
+ return false;
+ }
+
+ /***
+ * Called by the Audio framework / HAL when the metadata of the stream's
+ * source has been changed.
+ ***/
+ virtual void UpdateSourceMetadata(const source_metadata*) const {};
+
+ /***
+ * Return the current BluetoothStreamState
+ ***/
+ virtual BluetoothStreamState GetState() const {
+ return static_cast<BluetoothStreamState>(0);
+ }
- // Unregister this BluetoothAudioPort from BluetoothAudioSessionControl.
- // Audio HAL must delete this BluetoothAudioPort after calling this.
- void TearDown();
+ /***
+ * Set the current BluetoothStreamState
+ ***/
+ virtual void SetState(BluetoothStreamState state) {}
- // 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;
+ virtual bool IsA2dp() const { return false; }
- // WAR to support Mono mode / 16 bits per sample
- void ForcePcmStereoToMono(bool force) {
- is_stereo_to_mono_ = force;
- }
+ virtual bool GetPreferredDataIntervalUs(size_t* interval_us) const {
+ return false;
+ };
+
+ virtual size_t WriteData(const void* buffer, size_t bytes) const {
+ return 0;
+ };
+ virtual size_t ReadData(void* buffer, size_t bytes) const { return 0; };
+};
+
+namespace aidl {
+
+using ::aidl::android::hardware::bluetooth::audio::BluetoothAudioStatus;
+using ::aidl::android::hardware::bluetooth::audio::SessionType;
+
+class BluetoothAudioPortAidl : public BluetoothAudioPort {
+ public:
+ BluetoothAudioPortAidl();
+ virtual ~BluetoothAudioPortAidl() = default;
+
+ bool SetUp(audio_devices_t devices) override;
+
+ void TearDown() override;
+
+ void ForcePcmStereoToMono(bool force) override { 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();
+ bool Start() override;
+ bool Suspend() override;
+ void Stop() override;
- // 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;
+ bool GetPresentationPosition(uint64_t* delay_ns, uint64_t* byte,
+ timespec* timestamp) const override;
- // 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;
+ void UpdateSourceMetadata(
+ const source_metadata* source_metadata) const override;
- void UpdateSinkMetadata(const sink_metadata* sink_metadata) const;
+ /***
+ * Called by the Audio framework / HAL when the metadata of the stream's
+ * sink has been changed.
+ ***/
+ virtual void UpdateSinkMetadata(const sink_metadata* sink_metadata) const;
- // Return the current BluetoothStreamState
- BluetoothStreamState GetState() const;
+ BluetoothStreamState GetState() const override;
- // Set the current BluetoothStreamState
- void SetState(BluetoothStreamState state);
+ void SetState(BluetoothStreamState state) override;
- bool IsA2dp() const {
- return session_type_ == SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH ||
- session_type_ == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH;
+ bool IsA2dp() const override {
+ return session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
+ session_type_ ==
+ SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH;
}
- bool GetPreferredDataIntervalUs(size_t* interval_us) const;
+ bool GetPreferredDataIntervalUs(size_t* interval_us) const override;
protected:
uint16_t cookie_;
BluetoothStreamState state_;
- SessionType_2_1 session_type_;
+ SessionType session_type_;
// WR to support Mono: True if fetching Stereo and mixing into Mono
bool is_stereo_to_mono_ = false;
- bool in_use() const;
+ virtual 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.
+ // BluetoothAudioPortAidl 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 ControlResultHandler(const BluetoothAudioStatus& status);
void SessionChangedHandler();
};
-class BluetoothAudioPortOut : public BluetoothAudioPort {
+class BluetoothAudioPortAidlOut : public BluetoothAudioPortAidl {
public:
- ~BluetoothAudioPortOut() = default;
+ ~BluetoothAudioPortAidlOut();
// 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;
+ size_t WriteData(const void* buffer, size_t bytes) const override;
+ bool LoadAudioConfig(audio_config_t* audio_cfg) const override;
};
-class BluetoothAudioPortIn : public BluetoothAudioPort {
+class BluetoothAudioPortAidlIn : public BluetoothAudioPortAidl {
public:
- ~BluetoothAudioPortIn() = default;
+ ~BluetoothAudioPortAidlIn();
// 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;
+ size_t ReadData(void* buffer, size_t bytes) const override;
+ bool LoadAudioConfig(audio_config_t* audio_cfg) const override;
};
+} // namespace aidl
} // namespace audio
} // namespace bluetooth
} // namespace android
diff --git a/system/audio_bluetooth_hw/device_port_proxy_hidl.cc b/system/audio_bluetooth_hw/device_port_proxy_hidl.cc
new file mode 100644
index 0000000000..fbe7745f73
--- /dev/null
+++ b/system/audio_bluetooth_hw/device_port_proxy_hidl.cc
@@ -0,0 +1,608 @@
+/*
+ * Copyright 2022 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 "BTAudioHalDeviceProxyHIDL"
+
+#include "device_port_proxy_hidl.h"
+
+#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 "stream_apis.h"
+#include "utils.h"
+
+namespace android {
+namespace bluetooth {
+namespace audio {
+namespace hidl {
+
+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 BluetoothAudioStatusHidl =
+ ::android::hardware::bluetooth::audio::V2_0::Status;
+using ControlResultCallback = std::function<void(
+ uint16_t cookie, bool start_resp, const BluetoothAudioStatusHidl& 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
+
+BluetoothAudioPortHidl::BluetoothAudioPortHidl()
+ : session_type_hidl_(SessionType_2_1::UNKNOWN),
+ cookie_(android::bluetooth::audio::kObserversCookieUndefined),
+ state_(BluetoothStreamState::DISABLED) {}
+
+BluetoothAudioPortHidlOut::~BluetoothAudioPortHidlOut() {
+ if (BluetoothAudioPortHidl::in_use()) BluetoothAudioPortHidl::TearDown();
+}
+
+BluetoothAudioPortHidlIn::~BluetoothAudioPortHidlIn() {
+ if (BluetoothAudioPortHidl::in_use()) BluetoothAudioPortHidl::TearDown();
+}
+
+bool BluetoothAudioPortHidl::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 BluetoothAudioStatusHidl& 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_hidl_, cbacks);
+ LOG(INFO) << __func__ << ": session_type=" << toString(session_type_hidl_)
+ << ", cookie=" << StringPrintf("%#hx", cookie_);
+
+ return (cookie_ != android::bluetooth::audio::kObserversCookieUndefined);
+}
+
+bool BluetoothAudioPortHidl::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_hidl_ = 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_hidl_ =
+ 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_hidl_ = 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_hidl_ = 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_hidl_ = 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_hidl_)) {
+ LOG(ERROR) << __func__ << ": device=" << StringPrintf("%#x", device)
+ << ", session_type=" << toString(session_type_hidl_)
+ << " is not ready";
+ return false;
+ }
+ return true;
+}
+
+void BluetoothAudioPortHidl::TearDown() {
+ if (!in_use()) {
+ LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_hidl_)
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
+ << " unknown monitor";
+ return;
+ }
+
+ LOG(INFO) << __func__ << ": session_type=" << toString(session_type_hidl_)
+ << ", cookie=" << StringPrintf("%#hx", cookie_);
+ BluetoothAudioSessionControl_2_1::UnregisterControlResultCback(
+ session_type_hidl_, cookie_);
+ cookie_ = android::bluetooth::audio::kObserversCookieUndefined;
+}
+
+void BluetoothAudioPortHidl::ControlResultHandler(
+ const BluetoothAudioStatusHidl& 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_hidl_)
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
+ << ", previous_state=" << previous_state
+ << ", status=" << toString(status);
+
+ switch (previous_state) {
+ case BluetoothStreamState::STARTING:
+ if (status == BluetoothAudioStatusHidl::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_hidl_)
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
+ << ", previous_state=" << previous_state;
+ state_ = BluetoothStreamState::STANDBY;
+ }
+ break;
+ case BluetoothStreamState::SUSPENDING:
+ if (status == BluetoothAudioStatusHidl::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_hidl_)
+ << ", 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_hidl_)
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
+ << ", previous_state=" << previous_state;
+ return;
+ }
+ port_lock.unlock();
+ internal_cv_.notify_all();
+}
+
+void BluetoothAudioPortHidl::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_hidl_)
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
+ << ", previous_state=" << previous_state;
+ state_ = BluetoothStreamState::DISABLED;
+ port_lock.unlock();
+ internal_cv_.notify_all();
+}
+
+bool BluetoothAudioPortHidl::in_use() const {
+ return (cookie_ != android::bluetooth::audio::kObserversCookieUndefined);
+}
+
+bool BluetoothAudioPortHidl::GetPreferredDataIntervalUs(
+ size_t* interval_us) const {
+ if (!in_use()) {
+ return false;
+ }
+
+ const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration&
+ hal_audio_cfg =
+ BluetoothAudioSessionControl_2_1::GetAudioConfig(session_type_hidl_);
+ if (hal_audio_cfg.getDiscriminator() !=
+ ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration::
+ hidl_discriminator::pcmConfig) {
+ return false;
+ }
+
+ const ::android::hardware::bluetooth::audio::V2_1::PcmParameters& pcm_cfg =
+ hal_audio_cfg.pcmConfig();
+ *interval_us = pcm_cfg.dataIntervalUs;
+ return true;
+}
+
+bool BluetoothAudioPortHidl::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_hidl_)
+ << ", 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_hidl_)
+ << ", 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_hidl_)
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
+ << " waiting for KNOWN";
+ return false;
+ }
+
+ return retval; // false if any failure like timeout
+}
+
+bool BluetoothAudioPortHidl::Start() {
+ if (!in_use()) {
+ LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use";
+ return false;
+ }
+
+ LOG(INFO) << __func__ << ": session_type=" << toString(session_type_hidl_)
+ << ", 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_hidl_)) {
+ retval = CondwaitState(BluetoothStreamState::STARTING);
+ } else {
+ LOG(ERROR) << __func__
+ << ": session_type=" << toString(session_type_hidl_)
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
+ << ", state=" << state_ << " Hal fails";
+ }
+ }
+
+ if (retval) {
+ LOG(INFO) << __func__ << ": session_type=" << toString(session_type_hidl_)
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
+ << ", state=" << state_
+ << ", mono=" << (is_stereo_to_mono_ ? "true" : "false")
+ << " done";
+ } else {
+ LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_hidl_)
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
+ << ", state=" << state_ << " failure";
+ }
+
+ return retval; // false if any failure like timeout
+}
+
+bool BluetoothAudioPortHidl::Suspend() {
+ if (!in_use()) {
+ LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use";
+ return false;
+ }
+
+ LOG(INFO) << __func__ << ": session_type=" << toString(session_type_hidl_)
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
+ << ", state=" << state_ << " request";
+ bool retval = false;
+ if (state_ == BluetoothStreamState::STARTED) {
+ state_ = BluetoothStreamState::SUSPENDING;
+ if (BluetoothAudioSessionControl_2_1::SuspendStream(session_type_hidl_)) {
+ retval = CondwaitState(BluetoothStreamState::SUSPENDING);
+ } else {
+ LOG(ERROR) << __func__
+ << ": session_type=" << toString(session_type_hidl_)
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
+ << ", state=" << state_ << " Hal fails";
+ }
+ }
+
+ if (retval) {
+ LOG(INFO) << __func__ << ": session_type=" << toString(session_type_hidl_)
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
+ << ", state=" << state_ << " done";
+ } else {
+ LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_hidl_)
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
+ << ", state=" << state_ << " failure";
+ }
+
+ return retval; // false if any failure like timeout
+}
+
+void BluetoothAudioPortHidl::Stop() {
+ if (!in_use()) {
+ LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use";
+ return;
+ }
+ LOG(INFO) << __func__ << ": session_type=" << toString(session_type_hidl_)
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
+ << ", state=" << state_ << " request";
+ state_ = BluetoothStreamState::DISABLED;
+ BluetoothAudioSessionControl_2_1::StopStream(session_type_hidl_);
+ LOG(INFO) << __func__ << ": session_type=" << toString(session_type_hidl_)
+ << ", cookie=" << StringPrintf("%#hx", cookie_)
+ << ", state=" << state_ << " done";
+}
+
+bool BluetoothAudioPortHidl::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_hidl_, delay_ns, bytes, timestamp);
+ LOG(VERBOSE) << __func__
+ << ": session_type=" << StringPrintf("%#hhx", session_type_hidl_)
+ << ", 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 BluetoothAudioPortHidl::UpdateSourceMetadata(
+ 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_hidl_)
+ << ", 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_hidl_,
+ source_metadata);
+}
+
+BluetoothStreamState BluetoothAudioPortHidl::GetState() const { return state_; }
+
+void BluetoothAudioPortHidl::SetState(BluetoothStreamState state) {
+ state_ = state;
+}
+
+size_t BluetoothAudioPortHidlOut::WriteData(const void* buffer,
+ size_t bytes) const {
+ if (!BluetoothAudioPortHidl::in_use()) return 0;
+ if (!BluetoothAudioPortHidl::is_stereo_to_mono_) {
+ return BluetoothAudioSessionControl_2_1::OutWritePcmData(session_type_hidl_,
+ 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_hidl_, dst.get(), write_frames * 2) *
+ 2;
+}
+
+size_t BluetoothAudioPortHidlIn::ReadData(void* buffer, size_t bytes) const {
+ if (!BluetoothAudioPortHidl::in_use()) return 0;
+ return BluetoothAudioSessionControl_2_1::InReadPcmData(session_type_hidl_,
+ buffer, bytes);
+}
+
+bool BluetoothAudioPortHidlIn::LoadAudioConfig(
+ audio_config_t* audio_cfg) const {
+ if (!BluetoothAudioPortHidl::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_hidl_);
+ 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_hidl_)
+ << ", cookie="
+ << StringPrintf("%#hx", BluetoothAudioPortHidl::cookie_)
+ << ", state=" << BluetoothAudioPortHidl::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 BluetoothAudioPortHidlOut::LoadAudioConfig(
+ audio_config_t* audio_cfg) const {
+ if (!BluetoothAudioPortHidl::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_hidl_);
+ 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_hidl_)
+ << ", cookie="
+ << StringPrintf("%#hx", BluetoothAudioPortHidl::cookie_)
+ << ", state=" << BluetoothAudioPortHidl::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 =
+ (BluetoothAudioPortHidl::is_stereo_to_mono_
+ ? AUDIO_CHANNEL_OUT_STEREO
+ : OutputChannelModeToAudioFormat(pcm_cfg.channelMode));
+ audio_cfg->format = BitsPerSampleToAudioFormat(pcm_cfg.bitsPerSample);
+ return true;
+}
+
+} // namespace hidl
+} // namespace audio
+} // namespace bluetooth
+} // namespace android \ No newline at end of file
diff --git a/system/audio_bluetooth_hw/device_port_proxy_hidl.h b/system/audio_bluetooth_hw/device_port_proxy_hidl.h
new file mode 100644
index 0000000000..f37370daaf
--- /dev/null
+++ b/system/audio_bluetooth_hw/device_port_proxy_hidl.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2022 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>
+
+#include "device_port_proxy.h"
+
+enum class BluetoothStreamState : uint8_t;
+
+namespace android {
+namespace bluetooth {
+namespace audio {
+namespace hidl {
+
+using SessionType_2_1 =
+ ::android::hardware::bluetooth::audio::V2_1::SessionType;
+
+class BluetoothAudioPortHidl : public BluetoothAudioPort {
+ public:
+ BluetoothAudioPortHidl();
+ virtual ~BluetoothAudioPortHidl() = default;
+
+ bool SetUp(audio_devices_t devices) override;
+
+ void TearDown() override;
+
+ void ForcePcmStereoToMono(bool force) override { is_stereo_to_mono_ = force; }
+
+ bool Start() override;
+
+ bool Suspend() override;
+
+ void Stop() override;
+
+ bool GetPresentationPosition(uint64_t* delay_ns, uint64_t* bytes,
+ timespec* timestamp) const override;
+
+ void UpdateSourceMetadata(
+ const source_metadata* source_metadata) const override;
+
+ BluetoothStreamState GetState() const override;
+
+ void SetState(BluetoothStreamState state) override;
+
+ bool IsA2dp() const override {
+ return session_type_hidl_ ==
+ SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH ||
+ session_type_hidl_ ==
+ SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH;
+ }
+
+ bool GetPreferredDataIntervalUs(size_t* interval_us) const override;
+
+ protected:
+ SessionType_2_1 session_type_hidl_;
+ uint16_t cookie_;
+ BluetoothStreamState state_;
+ // 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_;
+
+ 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 BluetoothAudioPortHidlOut : public BluetoothAudioPortHidl {
+ public:
+ ~BluetoothAudioPortHidlOut();
+
+ size_t WriteData(const void* buffer, size_t bytes) const override;
+ bool LoadAudioConfig(audio_config_t* audio_cfg) const override;
+};
+
+class BluetoothAudioPortHidlIn : public BluetoothAudioPortHidl {
+ public:
+ ~BluetoothAudioPortHidlIn();
+
+ size_t ReadData(void* buffer, size_t bytes) const override;
+ bool LoadAudioConfig(audio_config_t* audio_cfg) const override;
+};
+
+} // namespace hidl
+} // namespace audio
+} // namespace bluetooth
+} // namespace android \ No newline at end of file
diff --git a/system/audio_bluetooth_hw/stream_apis.cc b/system/audio_bluetooth_hw/stream_apis.cc
index 77e1bb08b0..5bc992309a 100644
--- a/system/audio_bluetooth_hw/stream_apis.cc
+++ b/system/audio_bluetooth_hw/stream_apis.cc
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include "device_port_proxy.h"
#define LOG_TAG "BTAudioHalStream"
#include <android-base/logging.h>
@@ -26,11 +27,11 @@
#include <time.h>
#include <unistd.h>
+#include "BluetoothAudioSession.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;
@@ -66,7 +67,7 @@ void out_calculate_feeding_delay_ms(const BluetoothStreamOut* out,
bool timestamp_fetched = false;
std::unique_lock<std::mutex> lock(out->mutex_);
- if (out->bluetooth_output_.GetPresentationPosition(
+ 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
@@ -76,7 +77,7 @@ void out_calculate_feeding_delay_ms(const BluetoothStreamOut* out,
delay_report_ms < kMaximumDelayMs) {
timestamp_fetched = true;
} else if (delay_report_ms >= kMaximumDelayMs) {
- LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState()
+ LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< ", delay_report=" << delay_report_ns << "ns abnormal";
}
}
@@ -91,10 +92,10 @@ void out_calculate_feeding_delay_ms(const BluetoothStreamOut* out,
if (timestamp != nullptr) {
clock_gettime(CLOCK_MONOTONIC, &absorbed_timestamp);
}
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
+ LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< " uses the legacy delay " << delay_report_ms << " ms";
}
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
+ 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";
@@ -139,14 +140,14 @@ void in_calculate_starving_delay_ms(const BluetoothStreamIn* in,
struct timespec dispersed_timestamp = {};
std::unique_lock<std::mutex> lock(in->mutex_);
- in->bluetooth_input_.GetPresentationPosition(
+ 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()
+ LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_->GetState()
<< ", delay=" << delay_report_ms
<< "ms, data=" << dispersed_bytes
<< " bytes, timestamp=" << dispersed_timestamp.tv_sec << "."
@@ -198,12 +199,12 @@ std::ostream& operator<<(std::ostream& os, const BluetoothStreamState& 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()
+ 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()
+ LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< ", sample_rate=" << out->sample_rate_ << " failed";
return out->sample_rate_;
}
@@ -211,7 +212,7 @@ static uint32_t out_get_sample_rate(const struct audio_stream* stream) {
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()
+ LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< ", sample_rate=" << out->sample_rate_;
return (rate == out->sample_rate_ ? 0 : -1);
}
@@ -220,7 +221,7 @@ 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()
+ LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< ", buffer_size=" << buffer_size;
return buffer_size;
}
@@ -229,13 +230,14 @@ 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()
+ 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";
+ LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_->GetState()
+ << ", channels=" << StringPrintf("%#x", out->channel_mask_)
+ << " failure";
return out->channel_mask_;
}
}
@@ -243,12 +245,12 @@ static audio_channel_mask_t out_get_channels(
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()
+ 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()
+ LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< ", format=" << out->format_ << " failure";
return out->format_;
}
@@ -256,7 +258,7 @@ static audio_format_t out_get_format(const struct audio_stream* stream) {
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()
+ LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< ", format=" << out->format_;
return (format == out->format_ ? 0 : -1);
}
@@ -268,23 +270,23 @@ static int out_standby(struct audio_stream* stream) {
// out->last_write_time_us_ = 0; unnecessary as a stale write time has same
// effect
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
+ LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< " being standby (suspend)";
- if (out->bluetooth_output_.GetState() == BluetoothStreamState::STARTED) {
+ if (out->bluetooth_output_->GetState() == BluetoothStreamState::STARTED) {
out->frames_rendered_ = 0;
- retval = (out->bluetooth_output_.Suspend() ? 0 : -EIO);
- } else if (out->bluetooth_output_.GetState() ==
+ retval = (out->bluetooth_output_->Suspend() ? 0 : -EIO);
+ } else if (out->bluetooth_output_->GetState() ==
BluetoothStreamState::STARTING ||
- out->bluetooth_output_.GetState() ==
+ out->bluetooth_output_->GetState() ==
BluetoothStreamState::SUSPENDING) {
- LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_.GetState()
+ LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< " NOT ready to be standby";
retval = -EBUSY;
} else {
- LOG(DEBUG) << __func__ << ": state=" << out->bluetooth_output_.GetState()
+ LOG(DEBUG) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< " standby already";
}
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
+ LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< " standby (suspend) retval=" << retval;
return retval;
@@ -292,7 +294,7 @@ static int out_standby(struct audio_stream* stream) {
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();
+ LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState();
return 0;
}
@@ -302,7 +304,7 @@ static int out_set_parameters(struct audio_stream* stream,
std::unique_lock<std::mutex> lock(out->mutex_);
int retval = 0;
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
+ LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< ", kvpairs=[" << kvpairs << "]";
std::unordered_map<std::string, std::string> params =
@@ -316,73 +318,78 @@ static int out_set_parameters(struct audio_stream* stream,
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)) {
+ 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_;
+ 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()
+ << ": 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()
+ 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()) {
+ out->bluetooth_output_->IsA2dp()) {
if (params["A2dpSuspended"] == "true") {
- LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState()
+ 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() !=
+ 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();
+ out->bluetooth_output_->Stop();
}
} else {
- LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState()
+ 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 (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()
+ LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< " stream param closing, disallow any writes?";
- if (out->bluetooth_output_.GetState() != BluetoothStreamState::DISABLED) {
+ if (out->bluetooth_output_->GetState() !=
+ BluetoothStreamState::DISABLED) {
out->frames_rendered_ = 0;
out->frames_presented_ = 0;
- out->bluetooth_output_.Stop();
+ out->bluetooth_output_->Stop();
}
}
}
if (params.find("exiting") != params.end()) {
if (params["exiting"] == "1") {
- LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState()
+ LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< " stream param exiting";
- if (out->bluetooth_output_.GetState() != BluetoothStreamState::DISABLED) {
+ if (out->bluetooth_output_->GetState() !=
+ BluetoothStreamState::DISABLED) {
out->frames_rendered_ = 0;
out->frames_presented_ = 0;
- out->bluetooth_output_.Stop();
+ out->bluetooth_output_->Stop();
}
}
}
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
+ LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< ", kvpairs=[" << kvpairs << "], retval=" << retval;
return retval;
}
@@ -392,18 +399,18 @@ static char* out_get_parameters(const struct audio_stream* stream,
const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
std::unique_lock<std::mutex> lock(out->mutex_);
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
+ 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()
+ 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()
+ LOG(ERROR) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< " failed to get audio config";
}
@@ -467,7 +474,7 @@ static char* out_get_parameters(const struct audio_stream* stream,
result += ptr.first + "=" + ptr.second + ";";
}
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
+ LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< ", result=[" << result << "]";
return strdup(result.c_str());
}
@@ -476,7 +483,7 @@ 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()
+ LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< ", latency=" << latency_ms << "ms";
return latency_ms;
}
@@ -484,7 +491,7 @@ static uint32_t out_get_latency_ms(const struct audio_stream_out* stream) {
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()
+ LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< ", Left=" << left << ", Right=" << right;
return -1;
}
@@ -495,14 +502,15 @@ static ssize_t out_write(struct audio_stream_out* stream, const void* buffer,
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()
+ 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()
+ LOG(ERROR) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< " failed to resume";
- if (out->bluetooth_output_.GetState() == BluetoothStreamState::DISABLED) {
+ if (out->bluetooth_output_->GetState() ==
+ BluetoothStreamState::DISABLED) {
// drop data for cases of A2dpSuspended=true / closing=true
totalWritten = bytes;
}
@@ -512,7 +520,7 @@ static ssize_t out_write(struct audio_stream_out* stream, const void* buffer,
lock.lock();
}
lock.unlock();
- totalWritten = out->bluetooth_output_.WriteData(buffer, bytes);
+ totalWritten = out->bluetooth_output_->WriteData(buffer, bytes);
lock.lock();
struct timespec ts = {.tv_sec = 0, .tv_nsec = 0};
@@ -563,7 +571,7 @@ static int out_get_render_position(const struct audio_stream_out* stream,
*dsp_frames = 0;
}
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
+ LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< ", dsp_frames=" << *dsp_frames;
return 0;
}
@@ -571,7 +579,7 @@ static int out_get_render_position(const struct audio_stream_out* stream,
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()
+ LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< ", effect=" << effect;
return 0;
}
@@ -579,7 +587,7 @@ static int out_add_audio_effect(const struct audio_stream* stream,
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()
+ LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< ", effect=" << effect;
return 0;
}
@@ -588,7 +596,7 @@ 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()
+ LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< ", timestamp=" << *timestamp;
return -EINVAL;
}
@@ -597,23 +605,23 @@ 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()
+ LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< ", pausing (suspend)";
- if (out->bluetooth_output_.GetState() == BluetoothStreamState::STARTED) {
+ if (out->bluetooth_output_->GetState() == BluetoothStreamState::STARTED) {
out->frames_rendered_ = 0;
- retval = (out->bluetooth_output_.Suspend() ? 0 : -EIO);
- } else if (out->bluetooth_output_.GetState() ==
+ retval = (out->bluetooth_output_->Suspend() ? 0 : -EIO);
+ } else if (out->bluetooth_output_->GetState() ==
BluetoothStreamState::STARTING ||
- out->bluetooth_output_.GetState() ==
+ out->bluetooth_output_->GetState() ==
BluetoothStreamState::SUSPENDING) {
- LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_.GetState()
+ LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< " NOT ready to pause?!";
retval = -EBUSY;
} else {
- LOG(DEBUG) << __func__ << ": state=" << out->bluetooth_output_.GetState()
+ LOG(DEBUG) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< " paused already";
}
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
+ LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< ", pausing (suspend) retval=" << retval;
return retval;
@@ -624,27 +632,27 @@ static int out_resume(struct audio_stream_out* stream) {
std::unique_lock<std::mutex> lock(out->mutex_);
int retval = 0;
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
+ 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() ==
+ 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() ==
+ out->bluetooth_output_->GetState() ==
BluetoothStreamState::SUSPENDING) {
- LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_.GetState()
+ LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< " NOT ready to resume?!";
retval = -EBUSY;
- } else if (out->bluetooth_output_.GetState() ==
+ } else if (out->bluetooth_output_->GetState() ==
BluetoothStreamState::DISABLED) {
- LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_.GetState()
+ LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< " NOT allow to resume?!";
retval = -EINVAL;
} else {
- LOG(DEBUG) << __func__ << ": state=" << out->bluetooth_output_.GetState()
+ LOG(DEBUG) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< " resumed already";
}
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
+ LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< ", resuming (start) retval=" << retval;
return retval;
@@ -659,7 +667,7 @@ static int out_get_presentation_position(const struct audio_stream_out* stream,
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()
+ LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< ", frames=" << *frames << ", timestamp=" << timestamp->tv_sec
<< "." << StringPrintf("%09ld", timestamp->tv_nsec) << "s";
return 0;
@@ -673,9 +681,9 @@ static void out_update_source_metadata(
if (source_metadata == nullptr || source_metadata->track_count == 0) {
return;
}
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
+ LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< ", " << source_metadata->track_count << " track(s)";
- out->bluetooth_output_.UpdateMetadata(source_metadata);
+ out->bluetooth_output_->UpdateSourceMetadata(source_metadata);
}
static size_t frame_count(size_t microseconds, uint32_t sample_rate) {
@@ -690,7 +698,19 @@ int adev_open_output_stream(struct audio_hw_device* dev,
const char* address __unused) {
*stream_out = nullptr;
auto* out = new BluetoothStreamOut{};
- if (!out->bluetooth_output_.SetUp(devices)) {
+ if (::aidl::android::hardware::bluetooth::audio::BluetoothAudioSession::
+ IsAidlAvailable()) {
+ out->bluetooth_output_ = std::make_unique<
+ ::android::bluetooth::audio::aidl::BluetoothAudioPortAidlOut>();
+ out->is_aidl = true;
+ } else {
+ out->bluetooth_output_ = std::make_unique<
+ ::android::bluetooth::audio::hidl::BluetoothAudioPortHidlOut>();
+ out->is_aidl = false;
+ }
+ if (!out->bluetooth_output_->SetUp(devices)) {
+ out->bluetooth_output_ = nullptr;
+ LOG(ERROR) << __func__ << ": cannot init HAL";
delete out;
return -EINVAL;
}
@@ -718,15 +738,17 @@ int adev_open_output_stream(struct audio_hw_device* dev,
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()
+ 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_)
+ 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);
+ out->bluetooth_output_->ForcePcmStereoToMono(true);
config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
}
out->sample_rate_ = config->sample_rate;
@@ -735,7 +757,7 @@ int adev_open_output_stream(struct audio_hw_device* dev,
// frame is number of samples per channel
size_t preferred_data_interval_us = kBluetoothDefaultOutputBufferMs * 1000;
- if (out->bluetooth_output_.GetPreferredDataIntervalUs(
+ if (out->bluetooth_output_->GetPreferredDataIntervalUs(
&preferred_data_interval_us) &&
preferred_data_interval_us != 0) {
out->preferred_data_interval_us = preferred_data_interval_us;
@@ -766,11 +788,11 @@ int adev_open_output_stream(struct audio_hw_device* dev,
bluetooth_device->opened_stream_outs_.push_back(out);
}
*stream_out = &out->stream_out_;
- LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState()
+ LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< ", sample_rate=" << out->sample_rate_
<< ", channels=" << StringPrintf("%#x", out->channel_mask_)
- << ", format=" << out->format_
- << ", preferred_data_interval_us=" << out->preferred_data_interval_us
+ << ", format=" << out->format_ << ", preferred_data_interval_us="
+ << out->preferred_data_interval_us
<< ", frames=" << out->frames_count_;
return 0;
}
@@ -778,20 +800,20 @@ int adev_open_output_stream(struct audio_hw_device* dev,
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()
+ 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) {
+ if (out->bluetooth_output_->GetState() != BluetoothStreamState::DISABLED) {
out->frames_rendered_ = 0;
out->frames_presented_ = 0;
- out->bluetooth_output_.Stop();
+ out->bluetooth_output_->Stop();
}
- out->bluetooth_output_.TearDown();
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
+ out->bluetooth_output_->TearDown();
+ LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState()
<< ", stopped";
delete out;
}
@@ -812,7 +834,7 @@ static uint32_t in_get_sample_rate(const struct audio_stream* stream) {
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()
+ LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_->GetState()
<< ", sample_rate=" << in->sample_rate_;
return (rate == in->sample_rate_ ? 0 : -ENOSYS);
}
@@ -821,7 +843,7 @@ 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()
+ LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_->GetState()
<< ", buffer_size=" << buffer_size;
return buffer_size;
}
@@ -829,12 +851,12 @@ static size_t in_get_buffer_size(const struct audio_stream* stream) {
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()
+ 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()
+ LOG(WARNING) << __func__ << ": state=" << in->bluetooth_input_->GetState()
<< ", channels=" << StringPrintf("%#x", in->channel_mask_)
<< " failure";
return in->channel_mask_;
@@ -844,12 +866,12 @@ static audio_channel_mask_t in_get_channels(const struct audio_stream* stream) {
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()
+ 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()
+ LOG(WARNING) << __func__ << ": state=" << in->bluetooth_input_->GetState()
<< ", format=" << in->format_ << " failure";
return in->format_;
}
@@ -857,7 +879,7 @@ static audio_format_t in_get_format(const struct audio_stream* stream) {
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()
+ LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_->GetState()
<< ", format=" << in->format_;
return (format == in->format_ ? 0 : -ENOSYS);
}
@@ -867,7 +889,7 @@ static bool in_state_transition_timeout(BluetoothStreamIn* in,
const BluetoothStreamState& state,
uint16_t timeout_ms) {
/* Don't loose suspend request, AF will not retry */
- while (in->bluetooth_input_.GetState() == state) {
+ while (in->bluetooth_input_->GetState() == state) {
lock.unlock();
usleep(1000);
lock.lock();
@@ -888,22 +910,22 @@ static int in_standby(struct audio_stream* stream) {
std::unique_lock<std::mutex> lock(in->mutex_);
int retval = 0;
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
+ 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()
+ 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() !=
+ 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()
+ LOG(DEBUG) << __func__ << ": state=" << in->bluetooth_input_->GetState()
<< " standby already";
return retval;
}
@@ -911,12 +933,12 @@ static int in_standby(struct audio_stream* stream) {
/* Give some time to suspend */
if (!in_state_transition_timeout(in, lock, BluetoothStreamState::SUSPENDING,
kBluetoothDefaultInputStateTimeoutMs)) {
- LOG(ERROR) << __func__ << ": state=" << in->bluetooth_input_.GetState()
+ LOG(ERROR) << __func__ << ": state=" << in->bluetooth_input_->GetState()
<< " NOT ready to by standby";
return 0;
}
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
+ LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_->GetState()
<< " standby (suspend) retval=" << retval;
return retval;
@@ -924,7 +946,7 @@ static int in_standby(struct audio_stream* stream) {
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();
+ LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_->GetState();
return 0;
}
@@ -935,7 +957,7 @@ static int in_set_parameters(struct audio_stream* stream, const char* kvpairs) {
int retval = 0;
LOG(INFO) << __func__
- << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState()
+ << ": NOT HANDLED! state=" << in->bluetooth_input_->GetState()
<< ", kvpairs=[" << kvpairs << "]";
std::unordered_map<std::string, std::string> params =
@@ -955,18 +977,18 @@ static char* in_get_parameters(const struct audio_stream* stream,
std::unique_lock<std::mutex> lock(in->mutex_);
LOG(VERBOSE) << __func__
- << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState()
+ << ": 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()
+ 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()
+ LOG(ERROR) << __func__ << ": state=" << in->bluetooth_input_->GetState()
<< " failed to get audio config";
}
@@ -985,7 +1007,7 @@ static char* in_get_parameters(const struct audio_stream* stream,
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()
+ LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_->GetState()
<< ", effect=" << effect;
return 0;
}
@@ -993,7 +1015,7 @@ static int in_add_audio_effect(const struct audio_stream* stream,
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()
+ LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_->GetState()
<< ", effect=" << effect;
return 0;
}
@@ -1001,7 +1023,7 @@ static int in_remove_audio_effect(const struct audio_stream* stream,
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();
+ << ": NOT HANDLED! state=" << in->bluetooth_input_->GetState();
return 0;
}
@@ -1017,41 +1039,41 @@ static ssize_t in_read(struct audio_stream_in* stream, void* buffer,
kBluetoothDefaultInputStateTimeoutMs))
return -EBUSY;
- if (in->bluetooth_input_.GetState() != BluetoothStreamState::STARTED) {
- LOG(INFO) << __func__ << ": state=" << in->bluetooth_input_.GetState()
+ 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()
+ 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() ==
+ 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()
+ LOG(WARNING) << __func__ << ": state=" << in->bluetooth_input_->GetState()
<< " NOT ready to start?!";
retval = -EBUSY;
- } else if (in->bluetooth_input_.GetState() ==
+ } else if (in->bluetooth_input_->GetState() ==
BluetoothStreamState::DISABLED) {
- LOG(WARNING) << __func__ << ": state=" << in->bluetooth_input_.GetState()
+ LOG(WARNING) << __func__ << ": state=" << in->bluetooth_input_->GetState()
<< " NOT allow to start?!";
retval = -EINVAL;
} else {
- LOG(DEBUG) << __func__ << ": state=" << in->bluetooth_input_.GetState()
+ LOG(DEBUG) << __func__ << ": state=" << in->bluetooth_input_->GetState()
<< " started already";
}
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
+ LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_->GetState()
<< ", starting (start) retval=" << retval;
if (retval) {
- LOG(ERROR) << __func__ << ": state=" << in->bluetooth_input_.GetState()
+ LOG(ERROR) << __func__ << ": state=" << in->bluetooth_input_->GetState()
<< " failed to start";
return retval;
}
}
lock.unlock();
- totalRead = in->bluetooth_input_.ReadData(buffer, bytes);
+ totalRead = in->bluetooth_input_->ReadData(buffer, bytes);
lock.lock();
struct timespec ts = {.tv_sec = 0, .tv_nsec = 0};
@@ -1067,7 +1089,7 @@ static ssize_t in_read(struct audio_stream_in* stream, void* buffer,
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();
+ << ": NOT HANDLED! state=" << in->bluetooth_input_->GetState();
return 0;
}
@@ -1079,8 +1101,8 @@ static int in_get_capture_position(const struct audio_stream_in* stream,
}
const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- if (in->bluetooth_input_.GetState() == BluetoothStreamState::STANDBY) {
- LOG(WARNING) << __func__ << ": state= " << in->bluetooth_input_.GetState();
+ if (in->bluetooth_input_->GetState() == BluetoothStreamState::STANDBY) {
+ LOG(WARNING) << __func__ << ": state= " << in->bluetooth_input_->GetState();
return -ENOSYS;
}
@@ -1092,7 +1114,7 @@ static int in_get_capture_position(const struct audio_stream_in* stream,
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();
+ << ": NOT HANDLED! state=" << in->bluetooth_input_->GetState();
return 0;
}
@@ -1100,7 +1122,7 @@ static int in_start(const struct audio_stream_in* stream) {
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();
+ << ": NOT HANDLED! state=" << in->bluetooth_input_->GetState();
return 0;
}
@@ -1110,7 +1132,7 @@ static int in_create_mmap_buffer(const struct audio_stream_in* stream,
struct audio_mmap_buffer_info* info) {
const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
LOG(VERBOSE) << __func__
- << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();
+ << ": NOT HANDLED! state=" << in->bluetooth_input_->GetState();
return -ENOSYS;
}
@@ -1119,7 +1141,7 @@ 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();
+ << ": NOT HANDLED! state=" << in->bluetooth_input_->GetState();
return -ENOSYS;
}
@@ -1129,7 +1151,7 @@ static int in_get_active_microphones(
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();
+ << ": NOT HANDLED! state=" << in->bluetooth_input_->GetState();
return -ENOSYS;
}
@@ -1138,7 +1160,7 @@ 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();
+ << ": NOT HANDLED! state=" << in->bluetooth_input_->GetState();
return -ENOSYS;
}
@@ -1147,7 +1169,7 @@ 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();
+ << ": NOT HANDLED! state=" << in->bluetooth_input_->GetState();
return -ENOSYS;
}
@@ -1160,10 +1182,17 @@ static void in_update_sink_metadata(struct audio_stream_in* stream,
}
const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(INFO) << __func__ << ": state=" << in->bluetooth_input_.GetState() << ", "
- << sink_metadata->track_count << " track(s)";
+ LOG(INFO) << __func__ << ": state=" << in->bluetooth_input_->GetState()
+ << ", " << sink_metadata->track_count << " track(s)";
- in->bluetooth_input_.UpdateSinkMetadata(sink_metadata);
+ if (!in->is_aidl) {
+ LOG(WARNING) << __func__
+ << " is only supported in AIDL but using HIDL now!";
+ return;
+ }
+ static_cast<::android::bluetooth::audio::aidl::BluetoothAudioPortAidl*>(
+ in->bluetooth_input_.get())
+ ->UpdateSinkMetadata(sink_metadata);
}
int adev_open_input_stream(struct audio_hw_device* dev,
@@ -1175,7 +1204,19 @@ int adev_open_input_stream(struct audio_hw_device* dev,
audio_source_t source __unused) {
*stream_in = nullptr;
auto* in = new BluetoothStreamIn{};
- if (!in->bluetooth_input_.SetUp(devices)) {
+ if (::aidl::android::hardware::bluetooth::audio::BluetoothAudioSession::
+ IsAidlAvailable()) {
+ in->bluetooth_input_ = std::make_unique<
+ ::android::bluetooth::audio::aidl::BluetoothAudioPortAidlIn>();
+ in->is_aidl = true;
+ } else {
+ in->bluetooth_input_ = std::make_unique<
+ ::android::bluetooth::audio::hidl::BluetoothAudioPortHidlIn>();
+ in->is_aidl = false;
+ }
+ if (!in->bluetooth_input_->SetUp(devices)) {
+ in->bluetooth_input_ = nullptr;
+ LOG(ERROR) << __func__ << ": cannot init HAL";
delete in;
return -EINVAL;
}
@@ -1208,8 +1249,8 @@ int adev_open_input_stream(struct audio_hw_device* dev,
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()
+ if (!in->bluetooth_input_->LoadAudioConfig(config)) {
+ LOG(ERROR) << __func__ << ": state=" << in->bluetooth_input_->GetState()
<< " failed to get audio config";
return -EINVAL;
}
@@ -1220,7 +1261,7 @@ int adev_open_input_stream(struct audio_hw_device* dev,
// frame is number of samples per channel
size_t preferred_data_interval_us = kBluetoothDefaultInputBufferMs * 1000;
- if (in->bluetooth_input_.GetPreferredDataIntervalUs(
+ if (in->bluetooth_input_->GetPreferredDataIntervalUs(
&preferred_data_interval_us) &&
preferred_data_interval_us != 0) {
in->preferred_data_interval_us = preferred_data_interval_us;
@@ -1233,7 +1274,7 @@ int adev_open_input_stream(struct audio_hw_device* dev,
in->frames_presented_ = 0;
*stream_in = &in->stream_in_;
- LOG(INFO) << __func__ << ": state=" << in->bluetooth_input_.GetState()
+ LOG(INFO) << __func__ << ": state=" << in->bluetooth_input_->GetState()
<< ", sample_rate=" << in->sample_rate_
<< ", channels=" << StringPrintf("%#x", in->channel_mask_)
<< ", format=" << in->format_
@@ -1247,12 +1288,12 @@ 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();
+ if (in->bluetooth_input_->GetState() != BluetoothStreamState::DISABLED) {
+ in->bluetooth_input_->Stop();
}
- in->bluetooth_input_.TearDown();
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
+ in->bluetooth_input_->TearDown();
+ LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_->GetState()
<< ", stopped";
delete in;
diff --git a/system/audio_bluetooth_hw/stream_apis.h b/system/audio_bluetooth_hw/stream_apis.h
index cf90281591..76845d9ee5 100644
--- a/system/audio_bluetooth_hw/stream_apis.h
+++ b/system/audio_bluetooth_hw/stream_apis.h
@@ -18,9 +18,11 @@
#include <hardware/audio.h>
#include <system/audio.h>
+
#include <list>
#include "device_port_proxy.h"
+#include "device_port_proxy_hidl.h"
constexpr unsigned int kBluetoothDefaultSampleRate = 44100;
constexpr audio_format_t kBluetoothDefaultAudioFormatBitsPerSample =
@@ -52,7 +54,9 @@ 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_;
+ std::unique_ptr<::android::bluetooth::audio::BluetoothAudioPort>
+ bluetooth_output_;
+ bool is_aidl;
int64_t last_write_time_us_;
// Audio PCM Configs
uint32_t sample_rate_;
@@ -83,7 +87,9 @@ 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_;
+ std::unique_ptr<::android::bluetooth::audio::BluetoothAudioPort>
+ bluetooth_input_;
+ bool is_aidl;
int64_t last_read_time_us_;
// Audio PCM Configs
uint32_t sample_rate_;
diff --git a/system/audio_hal_interface/Android.bp b/system/audio_hal_interface/Android.bp
index ac8b4105d4..49175192d3 100644
--- a/system/audio_hal_interface/Android.bp
+++ b/system/audio_hal_interface/Android.bp
@@ -23,7 +23,6 @@ cc_library_static {
shared_libs: [
"android.hardware.bluetooth.audio@2.0",
"android.hardware.bluetooth.audio@2.1",
- "android.hardware.bluetooth.audio@2.2",
"libhidlbase",
],
static_libs: [
@@ -85,7 +84,6 @@ cc_test {
shared_libs: [
"android.hardware.bluetooth.audio@2.0",
"android.hardware.bluetooth.audio@2.1",
- "android.hardware.bluetooth.audio@2.2",
"android.hardware.bluetooth.audio-V1-ndk",
"libbinder_ndk",
"libcutils",
diff --git a/system/audio_hal_interface/a2dp_encoding.cc b/system/audio_hal_interface/a2dp_encoding.cc
index 854abfdb1e..d0028e1ef9 100644
--- a/system/audio_hal_interface/a2dp_encoding.cc
+++ b/system/audio_hal_interface/a2dp_encoding.cc
@@ -138,13 +138,11 @@ void set_remote_delay(uint16_t delay_report) {
}
// Set low latency buffer mode allowed or disallowed
-bool set_audio_low_latency_mode_allowed(bool allowed){
+void set_audio_low_latency_mode_allowed(bool allowed) {
if (HalVersionManager::GetHalTransport() ==
- BluetoothAudioHalTransport::HIDL) {
- hidl::a2dp::set_low_latency_mode_allowed(allowed);
- return true;
+ BluetoothAudioHalTransport::AIDL) {
+ aidl::a2dp::set_low_latency_mode_allowed(allowed);
}
- return false;
}
} // namespace a2dp
diff --git a/system/audio_hal_interface/a2dp_encoding.h b/system/audio_hal_interface/a2dp_encoding.h
index 8e149ac55e..51d5c9f309 100644
--- a/system/audio_hal_interface/a2dp_encoding.h
+++ b/system/audio_hal_interface/a2dp_encoding.h
@@ -44,7 +44,7 @@ void cleanup();
bool setup_codec();
// Set low latency buffer mode allowed or disallowed
-bool set_audio_low_latency_mode_allowed(bool allowed);
+void set_audio_low_latency_mode_allowed(bool allowed);
// Send command to the BluetoothAudio HAL: StartSession, EndSession,
// StreamStarted, StreamSuspended
diff --git a/system/audio_hal_interface/a2dp_encoding_host.cc b/system/audio_hal_interface/a2dp_encoding_host.cc
index 9ffff8b0d7..b0b6340c66 100644
--- a/system/audio_hal_interface/a2dp_encoding_host.cc
+++ b/system/audio_hal_interface/a2dp_encoding_host.cc
@@ -244,8 +244,7 @@ void end_session() {
remote_delay_report_ = 0;
}
-bool set_audio_low_latency_mode_allowed(bool allowed){
- return true;
+void set_audio_low_latency_mode_allowed(bool allowed){
}
diff --git a/system/audio_hal_interface/aidl/a2dp_encoding.cc b/system/audio_hal_interface/aidl/a2dp_encoding.cc
index 551398c00d..da1cb432d6 100644
--- a/system/audio_hal_interface/aidl/a2dp_encoding.cc
+++ b/system/audio_hal_interface/aidl/a2dp_encoding.cc
@@ -208,6 +208,7 @@ uint16_t remote_delay = 0;
bool btaudio_a2dp_disabled = false;
bool is_configured = false;
+bool is_low_latency_mode_allowed = false;
BluetoothAudioCtrlAck a2dp_ack_to_bt_audio_ctrl_ack(tA2DP_CTRL_ACK ack) {
switch (ack) {
@@ -470,6 +471,7 @@ void start_session() {
LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled";
return;
}
+ active_hal_interface->SetLowLatencyModeAllowed(is_low_latency_mode_allowed);
active_hal_interface->StartSession();
}
@@ -552,6 +554,16 @@ void set_remote_delay(uint16_t delay_report) {
->SetRemoteDelay(delay_report);
}
+// Set low latency buffer mode allowed or disallowed
+void set_low_latency_mode_allowed(bool allowed) {
+ is_low_latency_mode_allowed = allowed;
+ if (!is_hal_enabled()) {
+ LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled";
+ return;
+ }
+ active_hal_interface->SetLowLatencyModeAllowed(allowed);
+}
+
} // namespace a2dp
} // namespace aidl
} // namespace audio
diff --git a/system/audio_hal_interface/aidl/a2dp_encoding.h b/system/audio_hal_interface/aidl/a2dp_encoding.h
index c18adbc21a..a49c767589 100644
--- a/system/audio_hal_interface/aidl/a2dp_encoding.h
+++ b/system/audio_hal_interface/aidl/a2dp_encoding.h
@@ -81,6 +81,10 @@ size_t read(uint8_t* p_buf, uint32_t len);
***/
void set_remote_delay(uint16_t delay_report);
+/***
+ * Set low latency buffer mode allowed or disallowed
+ ***/
+void set_low_latency_mode_allowed(bool allowed);
} // namespace a2dp
} // namespace aidl
} // namespace audio
diff --git a/system/audio_hal_interface/aidl/audio_aidl_interfaces.h b/system/audio_hal_interface/aidl/audio_aidl_interfaces.h
index 9eb606f079..3c25d24d35 100644
--- a/system/audio_hal_interface/aidl/audio_aidl_interfaces.h
+++ b/system/audio_hal_interface/aidl/audio_aidl_interfaces.h
@@ -37,7 +37,6 @@
#include <aidl/android/hardware/bluetooth/audio/AudioConfiguration.h>
#include <aidl/android/hardware/bluetooth/audio/AudioLocation.h>
#include <aidl/android/hardware/bluetooth/audio/BluetoothAudioStatus.h>
-#include <aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.h>
#include <aidl/android/hardware/bluetooth/audio/ChannelMode.h>
#include <aidl/android/hardware/bluetooth/audio/CodecCapabilities.h>
#include <aidl/android/hardware/bluetooth/audio/CodecConfiguration.h>
@@ -45,16 +44,17 @@
#include <aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.h>
#include <aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.h>
#include <aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.h>
+#include <aidl/android/hardware/bluetooth/audio/LatencyMode.h>
#include <aidl/android/hardware/bluetooth/audio/Lc3Capabilities.h>
#include <aidl/android/hardware/bluetooth/audio/Lc3Configuration.h>
#include <aidl/android/hardware/bluetooth/audio/LdacCapabilities.h>
#include <aidl/android/hardware/bluetooth/audio/LdacChannelMode.h>
#include <aidl/android/hardware/bluetooth/audio/LdacConfiguration.h>
#include <aidl/android/hardware/bluetooth/audio/LdacQualityIndex.h>
+#include <aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.h>
#include <aidl/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.h>
#include <aidl/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.h>
#include <aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.h>
-#include <aidl/android/hardware/bluetooth/audio/LeAudioMode.h>
#include <aidl/android/hardware/bluetooth/audio/PcmCapabilities.h>
#include <aidl/android/hardware/bluetooth/audio/PcmConfiguration.h>
#include <aidl/android/hardware/bluetooth/audio/PresentationPosition.h>
@@ -63,8 +63,6 @@
#include <aidl/android/hardware/bluetooth/audio/SbcChannelMode.h>
#include <aidl/android/hardware/bluetooth/audio/SbcConfiguration.h>
#include <aidl/android/hardware/bluetooth/audio/SessionType.h>
-#include <aidl/android/hardware/bluetooth/audio/UnicastConfiguration.h>
-
#ifdef LOG_INFO
diff --git a/system/audio_hal_interface/aidl/bluetooth_audio_port_impl.cc b/system/audio_hal_interface/aidl/bluetooth_audio_port_impl.cc
index bd5f4b1a02..49edde2e73 100644
--- a/system/audio_hal_interface/aidl/bluetooth_audio_port_impl.cc
+++ b/system/audio_hal_interface/aidl/bluetooth_audio_port_impl.cc
@@ -16,6 +16,7 @@
#include "bluetooth_audio_port_impl.h"
+#include "btif/include/btif_common.h"
#include "common/stop_watch_legacy.h"
namespace bluetooth {
@@ -132,6 +133,13 @@ ndk::ScopedAStatus BluetoothAudioPortImpl::updateSinkMetadata(
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus BluetoothAudioPortImpl::setLatencyMode(
+ LatencyMode latency_mode) {
+ bool is_low_latency = latency_mode == LatencyMode::LOW_LATENCY ? true : false;
+ invoke_switch_buffer_size_cb(is_low_latency);
+ return ndk::ScopedAStatus::ok();
+}
+
PresentationPosition::TimeSpec BluetoothAudioPortImpl::timespec_convert_to_hal(
const timespec& ts) {
return {.tvSec = static_cast<int64_t>(ts.tv_sec),
diff --git a/system/audio_hal_interface/aidl/bluetooth_audio_port_impl.h b/system/audio_hal_interface/aidl/bluetooth_audio_port_impl.h
index 99823cee5d..30d98b25b1 100644
--- a/system/audio_hal_interface/aidl/bluetooth_audio_port_impl.h
+++ b/system/audio_hal_interface/aidl/bluetooth_audio_port_impl.h
@@ -26,7 +26,9 @@ namespace aidl {
using ::aidl::android::hardware::audio::common::SinkMetadata;
using ::aidl::android::hardware::audio::common::SourceMetadata;
using ::aidl::android::hardware::bluetooth::audio::BnBluetoothAudioPort;
+using ::aidl::android::hardware::bluetooth::audio::CodecType;
using ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider;
+using ::aidl::android::hardware::bluetooth::audio::LatencyMode;
using ::aidl::android::hardware::bluetooth::audio::PresentationPosition;
class BluetoothAudioPortImpl : public BnBluetoothAudioPort {
@@ -50,6 +52,8 @@ class BluetoothAudioPortImpl : public BnBluetoothAudioPort {
ndk::ScopedAStatus updateSinkMetadata(
const SinkMetadata& sink_metadata) override;
+ ndk::ScopedAStatus setLatencyMode(LatencyMode latency_mode) override;
+
protected:
virtual ~BluetoothAudioPortImpl();
diff --git a/system/audio_hal_interface/aidl/client_interface.cc b/system/audio_hal_interface/aidl/client_interface.cc
index 9626ecdb40..6bf3bd7db2 100644
--- a/system/audio_hal_interface/aidl/client_interface.cc
+++ b/system/audio_hal_interface/aidl/client_interface.cc
@@ -232,6 +232,24 @@ bool BluetoothAudioClientInterface::UpdateAudioConfig(
return true;
}
+bool BluetoothAudioClientInterface::SetLowLatencyModeAllowed(bool allowed) {
+ is_low_latency_allowed_ = allowed;
+ if (provider_ == nullptr) {
+ LOG(INFO) << __func__
+ << ": BluetoothAudioHal nullptr";
+ return false;
+ }
+
+ auto aidl_retval = provider_->setLowLatencyModeAllowed(allowed);
+ if (!aidl_retval.isOk()) {
+ LOG(ERROR) << __func__ << ": BluetoothAudioHal failure: "
+ << aidl_retval.getDescription();
+ return false;
+ }
+ return true;
+}
+
+
int BluetoothAudioClientInterface::StartSession() {
std::lock_guard<std::mutex> guard(internal_mutex_);
if (provider_ == nullptr) {
@@ -249,9 +267,12 @@ int BluetoothAudioClientInterface::StartSession() {
std::unique_ptr<DataMQ> data_mq;
DataMQDesc mq_desc;
-
+ std::vector<LatencyMode> latency_modes = {LatencyMode::FREE};
+ if (is_low_latency_allowed_) {
+ latency_modes.push_back(LatencyMode::LOW_LATENCY);
+ }
auto aidl_retval = provider_->startSession(
- stack_if, transport_->GetAudioConfiguration(), &mq_desc);
+ stack_if, transport_->GetAudioConfiguration(), latency_modes, &mq_desc);
if (!aidl_retval.isOk()) {
LOG(FATAL) << __func__ << ": BluetoothAudioHal failure: "
<< aidl_retval.getDescription();
diff --git a/system/audio_hal_interface/aidl/client_interface.h b/system/audio_hal_interface/aidl/client_interface.h
index 8e443727da..e423585313 100644
--- a/system/audio_hal_interface/aidl/client_interface.h
+++ b/system/audio_hal_interface/aidl/client_interface.h
@@ -43,6 +43,7 @@ using ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioPort;
using ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider;
using ::aidl::android::hardware::bluetooth::audio::
IBluetoothAudioProviderFactory;
+using ::aidl::android::hardware::bluetooth::audio::LatencyMode;
using ::aidl::android::hardware::bluetooth::audio::PcmConfiguration;
using ::aidl::android::hardware::common::fmq::MQDescriptor;
@@ -84,6 +85,8 @@ class BluetoothAudioClientInterface {
bool UpdateAudioConfig(const AudioConfiguration& audioConfig);
+ bool SetLowLatencyModeAllowed(bool allowed);
+
void FlushAudioData();
static constexpr PcmConfiguration kInvalidPcmConfiguration = {};
@@ -117,6 +120,7 @@ class BluetoothAudioClientInterface {
static inline bool aidl_available = true;
IBluetoothTransportInstance* transport_;
std::vector<AudioCapabilities> capabilities_;
+ bool is_low_latency_allowed_{false};
};
/***
diff --git a/system/audio_hal_interface/aidl/codec_status.cc b/system/audio_hal_interface/aidl/codec_status.cc
index 0e4e93f680..996a67eb36 100644
--- a/system/audio_hal_interface/aidl/codec_status.cc
+++ b/system/audio_hal_interface/aidl/codec_status.cc
@@ -18,6 +18,8 @@
#include "codec_status.h"
+#include <unordered_set>
+
#include "a2dp_aac_constants.h"
#include "a2dp_sbc_constants.h"
#include "a2dp_vendor_aptx_constants.h"
@@ -456,23 +458,23 @@ bool UpdateOffloadingCapabilities(
audio_hal_capabilities =
BluetoothAudioSinkClientInterface::GetAudioCapabilities(
SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
- uint32_t codec_type_masks = static_cast<uint32_t>(CodecType::UNKNOWN);
+ std::unordered_set<CodecType> codec_type_set;
for (auto preference : framework_preference) {
switch (preference.codec_type) {
case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
- codec_type_masks |= static_cast<uint32_t>(CodecType::SBC);
+ codec_type_set.insert(CodecType::SBC);
break;
case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
- codec_type_masks |= static_cast<uint32_t>(CodecType::AAC);
+ codec_type_set.insert(CodecType::AAC);
break;
case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
- codec_type_masks |= static_cast<uint32_t>(CodecType::APTX);
+ codec_type_set.insert(CodecType::APTX);
break;
case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD:
- codec_type_masks |= static_cast<uint32_t>(CodecType::APTX_HD);
+ codec_type_set.insert(CodecType::APTX_HD);
break;
case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC:
- codec_type_masks |= static_cast<uint32_t>(CodecType::LDAC);
+ codec_type_set.insert(CodecType::LDAC);
break;
case BTAV_A2DP_CODEC_INDEX_SINK_SBC:
[[fallthrough]];
@@ -492,9 +494,9 @@ bool UpdateOffloadingCapabilities(
}
offloading_preference.clear();
for (auto capability : audio_hal_capabilities) {
- if ((static_cast<uint32_t>(
- capability.get<AudioCapabilities::a2dpCapabilities>().codecType) &
- codec_type_masks) != 0) {
+ auto codec_type =
+ capability.get<AudioCapabilities::a2dpCapabilities>().codecType;
+ if (codec_type_set.find(codec_type) != codec_type_set.end()) {
LOG(INFO) << __func__
<< ": enabled offloading capability=" << capability.toString();
offloading_preference.push_back(capability);
diff --git a/system/audio_hal_interface/aidl/le_audio_software.cc b/system/audio_hal_interface/aidl/le_audio_software.cc
index 58aa51622d..e555917fd0 100644
--- a/system/audio_hal_interface/aidl/le_audio_software.cc
+++ b/system/audio_hal_interface/aidl/le_audio_software.cc
@@ -36,9 +36,7 @@ using ::aidl::android::hardware::bluetooth::audio::ChannelMode;
using ::aidl::android::hardware::bluetooth::audio::CodecType;
using ::aidl::android::hardware::bluetooth::audio::Lc3Configuration;
using ::aidl::android::hardware::bluetooth::audio::LeAudioCodecConfiguration;
-using ::aidl::android::hardware::bluetooth::audio::LeAudioMode;
using ::aidl::android::hardware::bluetooth::audio::PcmConfiguration;
-using ::aidl::android::hardware::bluetooth::audio::UnicastConfiguration;
using ::bluetooth::audio::aidl::AudioConfiguration;
using ::bluetooth::audio::aidl::BluetoothAudioCtrlAck;
using ::bluetooth::audio::le_audio::LeAudioClientInterface;
@@ -385,6 +383,7 @@ bool hal_ucast_capability_to_stack_format(
auto sample_rate_hz = hal_lc3_capability.samplingFrequencyHz[0];
auto frame_duration_us = hal_lc3_capability.frameDurationUs[0];
auto octets_per_frame = hal_lc3_capability.octetsPerFrame[0];
+ auto channel_count = hal_capability.channelCountPerDevice;
if (sampling_freq_map.find(sample_rate_hz) == sampling_freq_map.end() ||
frame_duration_map.find(frame_duration_us) == frame_duration_map.end() ||
@@ -406,8 +405,8 @@ bool hal_ucast_capability_to_stack_format(
{.sampling_frequency = sampling_freq_map[sample_rate_hz],
.frame_duration = frame_duration_map[frame_duration_us],
.octets_per_codec_frame = octets_per_frame_map[octets_per_frame],
- .audio_channel_allocation = audio_location_map[supportedChannel]})};
-
+ .audio_channel_allocation = audio_location_map[supportedChannel],
+ .channel_count = static_cast<uint8_t>(channel_count)})};
return true;
}
@@ -471,8 +470,8 @@ AudioConfiguration offload_config_to_hal_audio_config(
.octetsPerFrame = static_cast<int32_t>(offload_config.octets_per_frame),
.blocksPerSdu = static_cast<int8_t>(offload_config.blocks_per_sdu),
};
- UnicastConfiguration ucast_config = {
- .peerDelay = static_cast<int32_t>(offload_config.peer_delay),
+ LeAudioConfiguration ucast_config = {
+ .peerDelayUs = static_cast<int32_t>(offload_config.peer_delay_ms * 1000),
.leAudioCodecConfig = LeAudioCodecConfiguration(lc3_config)};
for (auto& [handle, location] : offload_config.stream_map) {
@@ -482,11 +481,7 @@ AudioConfiguration offload_config_to_hal_audio_config(
});
}
- LeAudioConfiguration le_audio_config{
- .mode = LeAudioMode::UNICAST,
- .modeConfig = LeAudioConfiguration::LeAudioModeConfig(ucast_config),
- };
- return AudioConfiguration(le_audio_config);
+ return AudioConfiguration(ucast_config);
}
} // namespace le_audio
diff --git a/system/audio_hal_interface/aidl/transport_instance.h b/system/audio_hal_interface/aidl/transport_instance.h
index 0dc24cee12..1f47444a37 100644
--- a/system/audio_hal_interface/aidl/transport_instance.h
+++ b/system/audio_hal_interface/aidl/transport_instance.h
@@ -26,6 +26,7 @@ namespace audio {
namespace aidl {
using ::aidl::android::hardware::bluetooth::audio::AudioConfiguration;
+using ::aidl::android::hardware::bluetooth::audio::LatencyMode;
using ::aidl::android::hardware::bluetooth::audio::SessionType;
/***
@@ -58,6 +59,9 @@ class IBluetoothTransportInstance {
audio_config_.set<AudioConfiguration::leAudioConfig>(
audio_config.get<AudioConfiguration::leAudioConfig>());
break;
+ case AudioConfiguration::leAudioBroadcastConfig:
+ audio_config_.set<AudioConfiguration::leAudioBroadcastConfig>(
+ audio_config.get<AudioConfiguration::leAudioBroadcastConfig>());
}
}
diff --git a/system/audio_hal_interface/fuzzer/Android.bp b/system/audio_hal_interface/fuzzer/Android.bp
index f3ec5a7bad..f1724af3d4 100644
--- a/system/audio_hal_interface/fuzzer/Android.bp
+++ b/system/audio_hal_interface/fuzzer/Android.bp
@@ -43,7 +43,6 @@ cc_defaults {
"android.hardware.bluetooth.a2dp@1.0",
"android.hardware.bluetooth.audio@2.0",
"android.hardware.bluetooth.audio@2.1",
- "android.hardware.bluetooth.audio@2.2",
"android.system.suspend.control-V1-ndk",
"android.system.suspend-V1-ndk",
],
@@ -64,12 +63,12 @@ cc_defaults {
"libbt-utils",
"libbtdevice",
"libcgrouprc",
+ "libflatbuffers-cpp",
"libhidlbase",
"libbt-stack",
"libg722codec",
"libudrv-uipc",
"libbt-common",
- "liblc3codec",
"liblc3",
"libstatslog_bt",
"libvndksupport",
diff --git a/system/audio_hal_interface/fuzzer/libbt_audio_hal_client_interface_fuzzer.cpp b/system/audio_hal_interface/fuzzer/libbt_audio_hal_client_interface_fuzzer.cpp
index e32ff3684f..9f43485ed7 100644
--- a/system/audio_hal_interface/fuzzer/libbt_audio_hal_client_interface_fuzzer.cpp
+++ b/system/audio_hal_interface/fuzzer/libbt_audio_hal_client_interface_fuzzer.cpp
@@ -169,8 +169,6 @@ class TestSinkTransport
void ResetPresentationPosition() override{};
void LogBytesRead(size_t) override{};
-
- void SinkMetadataChanged(const sink_metadata_t&) override{};
};
class TestSourceTransport
@@ -204,8 +202,6 @@ class TestSourceTransport
void ResetPresentationPosition() override{};
void LogBytesWritten(size_t) override{};
-
- void SinkMetadataChanged(const sink_metadata_t&) override{};
};
class ClientInterfaceFuzzer {
diff --git a/system/audio_hal_interface/hal_version_manager.cc b/system/audio_hal_interface/hal_version_manager.cc
index d46f6a6640..a2c192f37d 100644
--- a/system/audio_hal_interface/hal_version_manager.cc
+++ b/system/audio_hal_interface/hal_version_manager.cc
@@ -48,30 +48,12 @@ BluetoothAudioHalTransport HalVersionManager::GetHalTransport() {
return BluetoothAudioHalTransport::AIDL;
case BluetoothAudioHalVersion::VERSION_2_0:
case BluetoothAudioHalVersion::VERSION_2_1:
- case BluetoothAudioHalVersion::VERSION_2_2:
return BluetoothAudioHalTransport::HIDL;
default:
return BluetoothAudioHalTransport::UNKNOWN;
}
}
-android::sp<IBluetoothAudioProvidersFactory_2_2>
-HalVersionManager::GetProvidersFactory_2_2() {
- std::lock_guard<std::mutex> guard(instance_ptr->mutex_);
- if (instance_ptr->hal_version_ != BluetoothAudioHalVersion::VERSION_2_2) {
- return nullptr;
- }
- android::sp<IBluetoothAudioProvidersFactory_2_2> providers_factory =
- IBluetoothAudioProvidersFactory_2_2::getService();
- CHECK(providers_factory)
- << "V2_2::IBluetoothAudioProvidersFactory::getService() failed";
-
- LOG(INFO) << "V2_2::IBluetoothAudioProvidersFactory::getService() returned "
- << providers_factory.get()
- << (providers_factory->isRemote() ? " (remote)" : " (local)");
- return providers_factory;
-}
-
android::sp<IBluetoothAudioProvidersFactory_2_1>
HalVersionManager::GetProvidersFactory_2_1() {
std::lock_guard<std::mutex> guard(instance_ptr->mutex_);
@@ -124,19 +106,6 @@ HalVersionManager::HalVersionManager() {
instance_count = instanceNames.size();
};
auto hidl_retval = service_manager->listManifestByInterface(
- kFullyQualifiedInterfaceName_2_2, 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_2;
- return;
- }
-
- hidl_retval = service_manager->listManifestByInterface(
kFullyQualifiedInterfaceName_2_1, listManifestByInterface_cb);
if (!hidl_retval.isOk()) {
LOG(FATAL) << __func__ << ": IServiceManager::listByInterface failure: "
diff --git a/system/audio_hal_interface/hal_version_manager.h b/system/audio_hal_interface/hal_version_manager.h
index 12a2ecacfe..99dc0e9311 100644
--- a/system/audio_hal_interface/hal_version_manager.h
+++ b/system/audio_hal_interface/hal_version_manager.h
@@ -16,8 +16,8 @@
#pragma once
-#include <android/hardware/bluetooth/audio/2.2/IBluetoothAudioProvidersFactory.h>
-#include <android/hardware/bluetooth/audio/2.2/types.h>
+#include <android/hardware/bluetooth/audio/2.1/IBluetoothAudioProvidersFactory.h>
+#include <android/hardware/bluetooth/audio/2.1/types.h>
namespace bluetooth {
namespace audio {
@@ -28,22 +28,17 @@ using IBluetoothAudioProvidersFactory_2_0 = ::android::hardware::bluetooth::
audio::V2_0::IBluetoothAudioProvidersFactory;
using IBluetoothAudioProvidersFactory_2_1 = ::android::hardware::bluetooth::
audio::V2_1::IBluetoothAudioProvidersFactory;
-using IBluetoothAudioProvidersFactory_2_2 = ::android::hardware::bluetooth::
- audio::V2_2::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";
-constexpr char kFullyQualifiedInterfaceName_2_2[] =
- "android.hardware.bluetooth.audio@2.2::IBluetoothAudioProvidersFactory";
enum class BluetoothAudioHalVersion : uint8_t {
- VERSION_2_0 = 0,
+ VERSION_UNAVAILABLE = 0,
+ VERSION_2_0,
VERSION_2_1,
- VERSION_2_2,
VERSION_AIDL_V1,
- VERSION_UNAVAILABLE,
};
enum class BluetoothAudioHalTransport : uint8_t {
@@ -61,9 +56,6 @@ class HalVersionManager {
static BluetoothAudioHalTransport GetHalTransport();
- static android::sp<IBluetoothAudioProvidersFactory_2_2>
- GetProvidersFactory_2_2();
-
static android::sp<IBluetoothAudioProvidersFactory_2_1>
GetProvidersFactory_2_1();
diff --git a/system/audio_hal_interface/hal_version_manager_host.cc b/system/audio_hal_interface/hal_version_manager_host.cc
index 8b1c781d2f..b680ce06ff 100644
--- a/system/audio_hal_interface/hal_version_manager_host.cc
+++ b/system/audio_hal_interface/hal_version_manager_host.cc
@@ -29,11 +29,6 @@ BluetoothAudioHalTransport HalVersionManager::GetHalTransport() {
return BluetoothAudioHalTransport::UNKNOWN;
}
-android::sp<IBluetoothAudioProvidersFactory_2_2>
-HalVersionManager::GetProvidersFactory_2_2() {
- return nullptr;
-}
-
android::sp<IBluetoothAudioProvidersFactory_2_1>
HalVersionManager::GetProvidersFactory_2_1() {
return nullptr;
diff --git a/system/audio_hal_interface/hidl/a2dp_encoding_hidl.cc b/system/audio_hal_interface/hidl/a2dp_encoding_hidl.cc
index 6372aef40f..beeb823518 100644
--- a/system/audio_hal_interface/hidl/a2dp_encoding_hidl.cc
+++ b/system/audio_hal_interface/hidl/a2dp_encoding_hidl.cc
@@ -163,8 +163,6 @@ class A2dpTransport
}
}
- void SinkMetadataChanged(const sink_metadata_t&) override {}
-
tA2DP_CTRL_CMD GetPendingCmd() const { return a2dp_pending_cmd_; }
void ResetPendingCmd() { a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE; }
@@ -553,15 +551,6 @@ void set_remote_delay(uint16_t delay_report) {
->SetRemoteDelay(delay_report);
}
-// Set low latency buffer mode allowed or disallowed
-void set_low_latency_mode_allowed(bool allowed) {
- if (!is_hal_2_0_enabled()) {
- LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled";
- return;
- }
- active_hal_interface->SetLowLatencyModeAllowed(allowed);
-}
-
} // namespace a2dp
} // namespace hidl
} // namespace audio
diff --git a/system/audio_hal_interface/hidl/a2dp_encoding_hidl.h b/system/audio_hal_interface/hidl/a2dp_encoding_hidl.h
index d8689b29fa..98a8f68632 100644
--- a/system/audio_hal_interface/hidl/a2dp_encoding_hidl.h
+++ b/system/audio_hal_interface/hidl/a2dp_encoding_hidl.h
@@ -57,9 +57,6 @@ 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);
-// Set low latency buffer mode allowed or disallowed
-void set_low_latency_mode_allowed(bool allowed);
-
} // namespace a2dp
} // namespace hidl
} // namespace audio
diff --git a/system/audio_hal_interface/hidl/client_interface_hidl.cc b/system/audio_hal_interface/hidl/client_interface_hidl.cc
index 95efe6d42d..056ca04b75 100644
--- a/system/audio_hal_interface/hidl/client_interface_hidl.cc
+++ b/system/audio_hal_interface/hidl/client_interface_hidl.cc
@@ -18,7 +18,7 @@
#include "client_interface_hidl.h"
-#include <android/hardware/bluetooth/audio/2.2/IBluetoothAudioPort.h>
+#include <android/hardware/bluetooth/audio/2.0/IBluetoothAudioPort.h>
#include <base/logging.h>
#include <hidl/MQDescriptor.h>
@@ -35,9 +35,8 @@ namespace hidl {
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
-using ::android::hardware::audio::common::V5_0::SinkMetadata;
using ::android::hardware::audio::common::V5_0::SourceMetadata;
-using ::android::hardware::bluetooth::audio::V2_2::IBluetoothAudioPort;
+using ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioPort;
using ::bluetooth::common::StopWatchLegacy;
using DataMQ = ::android::hardware::MessageQueue<
@@ -156,24 +155,6 @@ class BluetoothAudioPortImpl : public IBluetoothAudioPort {
return Void();
}
- Return<void> updateSinkMetadata(const SinkMetadata& sinkMetadata) override {
- StopWatchLegacy stop_watch(__func__);
- LOG(INFO) << __func__ << ": " << sinkMetadata.tracks.size() << " track(s)";
- // refer to StreamIn.impl.h within Audio HAL (AUDIO_HAL_VERSION_5_0)
- std::vector<record_track_metadata> metadata_vec;
- metadata_vec.reserve(sinkMetadata.tracks.size());
- for (const auto& metadata : sinkMetadata.tracks) {
- metadata_vec.push_back({
- .source = static_cast<audio_source_t>(metadata.source),
- .gain = metadata.gain,
- });
- }
- const sink_metadata_t sink_metadata = {.track_count = metadata_vec.size(),
- .tracks = metadata_vec.data()};
- transport_instance_->SinkMetadataChanged(sink_metadata);
- return Void();
- }
-
private:
IBluetoothTransportInstance* transport_instance_;
const android::sp<IBluetoothAudioProvider> provider_;
@@ -220,7 +201,6 @@ BluetoothAudioClientInterface::BluetoothAudioClientInterface(
IBluetoothTransportInstance* instance)
: provider_(nullptr),
provider_2_1_(nullptr),
- provider_2_2_(nullptr),
session_started_(false),
mDataMQ(nullptr),
transport_(instance) {
@@ -300,37 +280,6 @@ BluetoothAudioClientInterface::GetAudioCapabilities_2_1(
return capabilities_2_1;
}
-std::vector<AudioCapabilities_2_2>
-BluetoothAudioClientInterface::GetAudioCapabilities_2_2(
- SessionType_2_1 session_type_2_1) {
- std::vector<AudioCapabilities_2_2> capabilities_2_2(0);
- if (HalVersionManager::GetHalVersion() !=
- BluetoothAudioHalVersion::VERSION_2_2) {
- LOG(ERROR) << __func__ << ", can't get capability for HAL 2.2";
- return capabilities_2_2;
- }
-
- android::sp<IBluetoothAudioProvidersFactory_2_2> providersFactory =
- HalVersionManager::GetProvidersFactory_2_2();
- CHECK(providersFactory != nullptr)
- << "IBluetoothAudioProvidersFactory::getService() failed";
- auto getProviderCapabilities_cb =
- [&capabilities_2_2](
- const hidl_vec<AudioCapabilities_2_2>& audioCapabilities_2_2) {
- for (auto capability_2_2 : audioCapabilities_2_2) {
- capabilities_2_2.push_back(capability_2_2);
- }
- };
- auto hidl_retval = providersFactory->getProviderCapabilities_2_2(
- session_type_2_1, getProviderCapabilities_cb);
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__
- << ": BluetoothAudioHal::getProviderCapabilities failure: "
- << hidl_retval.description();
- }
- return capabilities_2_2;
-}
-
void BluetoothAudioClientInterface::FetchAudioProvider() {
if (provider_ != nullptr) {
LOG(WARNING) << __func__ << ": reflash";
@@ -467,74 +416,6 @@ void BluetoothAudioClientInterface::FetchAudioProvider_2_1() {
<< (provider_2_1_->isRemote() ? " (remote)" : " (local)");
}
-void BluetoothAudioClientInterface::FetchAudioProvider_2_2() {
- if (provider_2_2_ != nullptr) {
- LOG(WARNING) << __func__ << ": reflash";
- }
-
- android::sp<IBluetoothAudioProvidersFactory_2_2> providersFactory =
- HalVersionManager::GetProvidersFactory_2_2();
- 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_2_ = this->provider_2_2_, &openProvider_promise](
- BluetoothAudioStatus status,
- const android::sp<IBluetoothAudioProvider_2_2>& provider_2_2) {
- LOG(INFO) << "openProvider_cb(" << toString(status) << ")";
- if (status == BluetoothAudioStatus::SUCCESS) {
- provider_2_2_ = provider_2_2;
- }
- ALOGE_IF(!provider_2_2_, "Failed to open BluetoothAudio provider_2_2");
- openProvider_promise.set_value();
- };
- hidl_retval = providersFactory->openProvider_2_2(
- 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_2_ != nullptr);
-
- if (!provider_2_2_->linkToDeath(death_recipient_, 0).isOk()) {
- LOG(FATAL) << __func__ << ": BluetoothAudioDeathRecipient failure: "
- << hidl_retval.description();
- }
-
- LOG(INFO) << "IBluetoothAudioProvidersFactory::openProvider() returned "
- << provider_2_2_.get()
- << (provider_2_2_->isRemote() ? " (remote)" : " (local)");
-}
-
BluetoothAudioSinkClientInterface::BluetoothAudioSinkClientInterface(
IBluetoothSinkTransportInstance* sink,
bluetooth::common::MessageLoopThread* message_loop)
@@ -548,13 +429,6 @@ BluetoothAudioSinkClientInterface::BluetoothAudioSinkClientInterface(
}
if ((HalVersionManager::GetHalVersion() ==
- BluetoothAudioHalVersion::VERSION_2_2) &&
- (sink_->GetSessionType_2_1() != SessionType_2_1::UNKNOWN)) {
- FetchAudioProvider_2_2();
- return;
- }
-
- if ((HalVersionManager::GetHalVersion() ==
BluetoothAudioHalVersion::VERSION_2_1) &&
(sink_->GetSessionType_2_1() != SessionType_2_1::UNKNOWN)) {
FetchAudioProvider_2_1();
@@ -578,13 +452,6 @@ BluetoothAudioSinkClientInterface::~BluetoothAudioSinkClientInterface() {
<< hidl_retval.description();
}
}
- if (provider_2_2_ != nullptr) {
- auto hidl_retval = provider_2_2_->unlinkToDeath(death_recipient_);
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__ << ": BluetoothAudioDeathRecipient failure: "
- << hidl_retval.description();
- }
- }
}
BluetoothAudioSourceClientInterface::BluetoothAudioSourceClientInterface(
@@ -600,12 +467,6 @@ BluetoothAudioSourceClientInterface::BluetoothAudioSourceClientInterface(
}
if ((HalVersionManager::GetHalVersion() ==
- BluetoothAudioHalVersion::VERSION_2_2) &&
- (source_->GetSessionType_2_1() != SessionType_2_1::UNKNOWN)) {
- FetchAudioProvider_2_2();
- return;
- }
- if ((HalVersionManager::GetHalVersion() ==
BluetoothAudioHalVersion::VERSION_2_1) &&
(source_->GetSessionType_2_1() != SessionType_2_1::UNKNOWN)) {
FetchAudioProvider_2_1();
@@ -629,13 +490,6 @@ BluetoothAudioSourceClientInterface::~BluetoothAudioSourceClientInterface() {
<< hidl_retval.description();
}
}
- if (provider_2_2_ != nullptr) {
- auto hidl_retval = provider_2_2_->unlinkToDeath(death_recipient_);
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__ << ": BluetoothAudioDeathRecipient failure: "
- << hidl_retval.description();
- }
- }
}
bool BluetoothAudioClientInterface::UpdateAudioConfig(
@@ -692,61 +546,6 @@ bool BluetoothAudioClientInterface::UpdateAudioConfig_2_1(
return true;
}
-bool BluetoothAudioClientInterface::UpdateAudioConfig_2_2(
- const AudioConfiguration_2_2& audio_config_2_2) {
- 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_a2dp_offload_session =
- (transport_->GetSessionType_2_1() ==
- SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- bool is_leaudio_offload_session =
- (transport_->GetSessionType_2_1() ==
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
- transport_->GetSessionType_2_1() ==
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
- auto audio_config_discriminator = audio_config_2_2.getDiscriminator();
- bool is_software_audio_config =
- (is_software_session &&
- audio_config_discriminator ==
- AudioConfiguration_2_2::hidl_discriminator::pcmConfig);
- bool is_a2dp_offload_audio_config =
- (is_a2dp_offload_session &&
- audio_config_discriminator ==
- AudioConfiguration_2_2::hidl_discriminator::codecConfig);
- bool is_leaudio_offload_audio_config =
- (is_leaudio_offload_session &&
- audio_config_discriminator ==
- AudioConfiguration_2_2::hidl_discriminator::leAudioConfig);
- if (!is_software_audio_config && !is_a2dp_offload_audio_config &&
- !is_leaudio_offload_audio_config) {
- return false;
- }
-
- transport_->UpdateAudioConfiguration_2_2(audio_config_2_2);
-
- if (provider_2_2_ == nullptr) {
- LOG(INFO) << __func__
- << ": BluetoothAudioHal nullptr, update it as session started";
- return true;
- }
-
- ::android::hardware::Return<void> hidl_retval;
- hidl_retval = provider_2_2_->updateAudioConfiguration(audio_config_2_2);
-
- if (!hidl_retval.isOk()) {
- LOG(ERROR) << __func__
- << ": BluetoothAudioHal failure: " << hidl_retval.description();
- }
- return true;
-}
-
int BluetoothAudioClientInterface::StartSession() {
std::lock_guard<std::mutex> guard(internal_mutex_);
if (provider_ == nullptr) {
@@ -867,71 +666,6 @@ int BluetoothAudioClientInterface::StartSession_2_1() {
}
}
-int BluetoothAudioClientInterface::StartSession_2_2() {
- std::lock_guard<std::mutex> guard(internal_mutex_);
- if (provider_2_2_ == 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_2_);
-
- 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_2_->startSession_2_2(
- stack_if, transport_->GetAudioConfiguration_2_2(), 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 ||
- transport_->GetSessionType_2_1() ==
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
- transport_->GetSessionType_2_1() ==
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_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 (ack == BluetoothAudioCtrlAck::PENDING) {
@@ -941,9 +675,7 @@ void BluetoothAudioClientInterface::StreamStarted(
BluetoothAudioStatus status = BluetoothAudioCtrlAckToHalStatus(ack);
::android::hardware::Return<void> hidl_retval;
- if (provider_2_2_ != nullptr) {
- hidl_retval = provider_2_2_->streamStarted(status);
- } else if (provider_2_1_ != nullptr) {
+ if (provider_2_1_ != nullptr) {
hidl_retval = provider_2_1_->streamStarted(status);
} else if (provider_ != nullptr) {
hidl_retval = provider_->streamStarted(status);
@@ -967,9 +699,7 @@ void BluetoothAudioClientInterface::StreamSuspended(
BluetoothAudioStatus status = BluetoothAudioCtrlAckToHalStatus(ack);
::android::hardware::Return<void> hidl_retval;
- if (provider_2_2_ != nullptr) {
- hidl_retval = provider_2_2_->streamSuspended(status);
- } else if (provider_2_1_ != nullptr) {
+ if (provider_2_1_ != nullptr) {
hidl_retval = provider_2_1_->streamSuspended(status);
} else if (provider_ != nullptr) {
hidl_retval = provider_->streamSuspended(status);
@@ -995,9 +725,7 @@ int BluetoothAudioClientInterface::EndSession() {
mDataMQ = nullptr;
::android::hardware::Return<void> hidl_retval;
- if (provider_2_2_ != nullptr) {
- hidl_retval = provider_2_2_->endSession();
- } else if (provider_2_1_ != nullptr) {
+ if (provider_2_1_ != nullptr) {
hidl_retval = provider_2_1_->endSession();
} else if (provider_ != nullptr) {
hidl_retval = provider_->endSession();
@@ -1088,11 +816,8 @@ void BluetoothAudioClientInterface::RenewAudioProviderAndSession() {
// NOTE: must be invoked on the same thread where this
// BluetoothAudioClientInterface is running
auto hal_version = HalVersionManager::GetHalVersion();
- if ((hal_version == BluetoothAudioHalVersion::VERSION_2_2) &&
+ if ((hal_version == BluetoothAudioHalVersion::VERSION_2_1) &&
(transport_->GetSessionType_2_1() != SessionType_2_1::UNKNOWN)) {
- FetchAudioProvider_2_2();
- } else if ((hal_version == BluetoothAudioHalVersion::VERSION_2_1) &&
- (transport_->GetSessionType_2_1() != SessionType_2_1::UNKNOWN)) {
FetchAudioProvider_2_1();
} else if (transport_->GetSessionType() != SessionType::UNKNOWN) {
FetchAudioProvider();
@@ -1105,9 +830,7 @@ void BluetoothAudioClientInterface::RenewAudioProviderAndSession() {
LOG(INFO) << __func__ << ": Restart the session while audio HAL recovering";
session_started_ = false;
- if (provider_2_2_ != nullptr)
- StartSession_2_2();
- else if (provider_2_1_ != nullptr)
+ if (provider_2_1_ != nullptr)
StartSession_2_1();
else
StartSession();
@@ -1166,14 +889,6 @@ size_t BluetoothAudioSourceClientInterface::WriteAudioData(const uint8_t* p_buf,
return total_written;
}
-void BluetoothAudioClientInterface::SetLowLatencyModeAllowed(bool allowed) {
- if (!IsValid()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioHal is not valid";
- return;
- }
- provider_2_2_->setLowLatencyModeAllowed(allowed);
-}
-
} // namespace hidl
} // namespace audio
} // namespace bluetooth
diff --git a/system/audio_hal_interface/hidl/client_interface_hidl.h b/system/audio_hal_interface/hidl/client_interface_hidl.h
index cb36613bbb..2ca53e2a6e 100644
--- a/system/audio_hal_interface/hidl/client_interface_hidl.h
+++ b/system/audio_hal_interface/hidl/client_interface_hidl.h
@@ -16,8 +16,8 @@
#pragma once
-#include <android/hardware/bluetooth/audio/2.2/IBluetoothAudioProvider.h>
-#include <android/hardware/bluetooth/audio/2.2/types.h>
+#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 <time.h>
@@ -34,27 +34,20 @@ namespace bluetooth {
namespace audio {
namespace hidl {
-using ::android::hardware::bluetooth::audio::V2_2::IBluetoothAudioPort;
using AudioCapabilities =
::android::hardware::bluetooth::audio::V2_0::AudioCapabilities;
using AudioCapabilities_2_1 =
::android::hardware::bluetooth::audio::V2_1::AudioCapabilities;
-using AudioCapabilities_2_2 =
- ::android::hardware::bluetooth::audio::V2_2::AudioCapabilities;
using AudioConfiguration =
::android::hardware::bluetooth::audio::V2_0::AudioConfiguration;
using AudioConfiguration_2_1 =
::android::hardware::bluetooth::audio::V2_1::AudioConfiguration;
-using AudioConfiguration_2_2 =
- ::android::hardware::bluetooth::audio::V2_2::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 IBluetoothAudioProvider_2_2 =
- ::android::hardware::bluetooth::audio::V2_2::IBluetoothAudioProvider;
using PcmParameters =
::android::hardware::bluetooth::audio::V2_0::PcmParameters;
using PcmParameters_2_1 =
@@ -107,22 +100,13 @@ class IBluetoothTransportInstance {
: session_type_(sessionType),
session_type_2_1_(SessionType_2_1::UNKNOWN),
audio_config_(std::move(audioConfig)),
- audio_config_2_1_({}),
- audio_config_2_2_({}){};
+ 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)),
- audio_config_2_2_({}){};
- IBluetoothTransportInstance(SessionType_2_1 sessionType_2_1,
- AudioConfiguration_2_2 audioConfig_2_2)
- : session_type_(SessionType::UNKNOWN),
- session_type_2_1_(sessionType_2_1),
- audio_config_({}),
- audio_config_2_1_({}),
- audio_config_2_2_(std::move(audioConfig_2_2)){};
+ audio_config_2_1_(std::move(audioConfig_2_1)){};
virtual ~IBluetoothTransportInstance() = default;
SessionType GetSessionType() const { return session_type_; }
@@ -132,9 +116,6 @@ class IBluetoothTransportInstance {
AudioConfiguration_2_1 GetAudioConfiguration_2_1() const {
return audio_config_2_1_;
}
- AudioConfiguration_2_2 GetAudioConfiguration_2_2() const {
- return audio_config_2_2_;
- }
void UpdateAudioConfiguration(const AudioConfiguration& audio_config) {
audio_config_ = audio_config;
@@ -143,10 +124,6 @@ class IBluetoothTransportInstance {
const AudioConfiguration_2_1& audio_config_2_1) {
audio_config_2_1_ = audio_config_2_1;
}
- void UpdateAudioConfiguration_2_2(
- const AudioConfiguration_2_2& audio_config_2_2) {
- audio_config_2_2_ = audio_config_2_2;
- }
virtual BluetoothAudioCtrlAck StartRequest() = 0;
@@ -159,7 +136,6 @@ class IBluetoothTransportInstance {
timespec* data_position) = 0;
virtual void MetadataChanged(const source_metadata_t& source_metadata) = 0;
- virtual void SinkMetadataChanged(const sink_metadata_t& sink_metadata) = 0;
// Invoked when the transport is requested to reset presentation position
virtual void ResetPresentationPosition() = 0;
@@ -169,7 +145,6 @@ class IBluetoothTransportInstance {
const SessionType_2_1 session_type_2_1_;
AudioConfiguration audio_config_;
AudioConfiguration_2_1 audio_config_2_1_;
- AudioConfiguration_2_2 audio_config_2_2_;
};
// An IBluetoothSinkTransportInstance needs to be implemented by a Bluetooth
@@ -177,15 +152,12 @@ class IBluetoothTransportInstance {
// from Audio HAL.
class IBluetoothSinkTransportInstance : public IBluetoothTransportInstance {
public:
- IBluetoothSinkTransportInstance(SessionType_2_1 sessionType_2_1,
- AudioConfiguration_2_2 audioConfig_2_2)
- : IBluetoothTransportInstance{sessionType_2_1, audioConfig_2_2} {}
- 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} {}
+ IBluetoothSinkTransportInstance(SessionType_2_1 sessionType_2_1,
+ AudioConfiguration_2_1 audioConfig_2_1)
+ : IBluetoothTransportInstance{sessionType_2_1, audioConfig_2_1} {}
virtual ~IBluetoothSinkTransportInstance() = default;
// Invoked when the transport is requested to log bytes read
@@ -200,9 +172,6 @@ class IBluetoothSourceTransportInstance : public IBluetoothTransportInstance {
IBluetoothSourceTransportInstance(SessionType_2_1 sessionType_2_1,
AudioConfiguration_2_1 audioConfig_2_1)
: IBluetoothTransportInstance{sessionType_2_1, audioConfig_2_1} {}
- IBluetoothSourceTransportInstance(SessionType_2_1 sessionType_2_1,
- AudioConfiguration_2_2 audioConfig_2_2)
- : IBluetoothTransportInstance{sessionType_2_1, audioConfig_2_2} {}
virtual ~IBluetoothSourceTransportInstance() = default;
// Invoked when the transport is requested to log bytes written
@@ -223,8 +192,7 @@ class BluetoothAudioClientInterface {
virtual ~BluetoothAudioClientInterface() = default;
bool IsValid() const {
- return provider_ != nullptr || provider_2_1_ != nullptr ||
- provider_2_2_ != nullptr;
+ return provider_ != nullptr || provider_2_1_ != nullptr;
}
std::vector<AudioCapabilities> GetAudioCapabilities() const;
@@ -233,8 +201,6 @@ class BluetoothAudioClientInterface {
SessionType session_type);
static std::vector<AudioCapabilities_2_1> GetAudioCapabilities_2_1(
SessionType_2_1 session_type_2_1);
- static std::vector<AudioCapabilities_2_2> GetAudioCapabilities_2_2(
- SessionType_2_1 session_type_2_1);
void StreamStarted(const BluetoothAudioCtrlAck& ack);
@@ -242,7 +208,6 @@ class BluetoothAudioClientInterface {
int StartSession();
int StartSession_2_1();
- int StartSession_2_2();
// Renew the connection and usually is used when HIDL restarted
void RenewAudioProviderAndSession();
@@ -251,12 +216,9 @@ class BluetoothAudioClientInterface {
bool UpdateAudioConfig(const AudioConfiguration& audioConfig);
bool UpdateAudioConfig_2_1(const AudioConfiguration_2_1& audioConfig_2_1);
- bool UpdateAudioConfig_2_2(const AudioConfiguration_2_2& audioConfig_2_2);
void FlushAudioData();
- void SetLowLatencyModeAllowed(bool allowed);
-
static constexpr PcmParameters kInvalidPcmConfiguration = {
.sampleRate = SampleRate::RATE_UNKNOWN,
.channelMode = ChannelMode::UNKNOWN,
@@ -268,12 +230,9 @@ class BluetoothAudioClientInterface {
void FetchAudioProvider();
// Helper function to connect to an IBluetoothAudioProvider 2.1
void FetchAudioProvider_2_1();
- // Helper function to connect to an IBluetoothAudioProvider 2.2
- void FetchAudioProvider_2_2();
android::sp<IBluetoothAudioProvider> provider_;
android::sp<IBluetoothAudioProvider_2_1> provider_2_1_;
- android::sp<IBluetoothAudioProvider_2_2> provider_2_2_;
bool session_started_;
std::unique_ptr<::android::hardware::MessageQueue<
uint8_t, ::android::hardware::kSynchronizedReadWrite>>
@@ -284,7 +243,6 @@ class BluetoothAudioClientInterface {
IBluetoothTransportInstance* transport_;
std::vector<AudioCapabilities> capabilities_;
std::vector<AudioCapabilities_2_1> capabilities_2_1_;
- std::vector<AudioCapabilities_2_2> capabilities_2_2_;
};
// The client interface connects an IBluetoothTransportInstance to
diff --git a/system/audio_hal_interface/hidl/client_interface_hidl_unittest.cc b/system/audio_hal_interface/hidl/client_interface_hidl_unittest.cc
index 7defcdfbb4..7f45cb050e 100644
--- a/system/audio_hal_interface/hidl/client_interface_hidl_unittest.cc
+++ b/system/audio_hal_interface/hidl/client_interface_hidl_unittest.cc
@@ -164,8 +164,6 @@ class TestSinkTransport
}
void MetadataChanged(
const source_metadata_t& source_metadata __unused) override {}
- void SinkMetadataChanged(
- const sink_metadata_t& sink_metadata __unused) override {}
void ResetPresentationPosition() override{};
void LogBytesRead(size_t bytes_readed __unused) override{};
};
@@ -205,8 +203,6 @@ class TestSourceTransport
}
void MetadataChanged(
const source_metadata_t& source_metadata __unused) override {}
- void SinkMetadataChanged(
- const sink_metadata_t& sink_metadata __unused) override {}
void ResetPresentationPosition() override{};
void LogBytesWritten(size_t bytes_written __unused) override{};
};
diff --git a/system/audio_hal_interface/hidl/codec_status_hidl.h b/system/audio_hal_interface/hidl/codec_status_hidl.h
index 7f010b8d15..8ed431c80e 100644
--- a/system/audio_hal_interface/hidl/codec_status_hidl.h
+++ b/system/audio_hal_interface/hidl/codec_status_hidl.h
@@ -16,7 +16,7 @@
#pragma once
-#include <android/hardware/bluetooth/audio/2.2/types.h>
+#include <android/hardware/bluetooth/audio/2.1/types.h>
#include <vector>
diff --git a/system/audio_hal_interface/hidl/hearing_aid_software_encoding_hidl.cc b/system/audio_hal_interface/hidl/hearing_aid_software_encoding_hidl.cc
index 3bb48b6949..ed2f963dcf 100644
--- a/system/audio_hal_interface/hidl/hearing_aid_software_encoding_hidl.cc
+++ b/system/audio_hal_interface/hidl/hearing_aid_software_encoding_hidl.cc
@@ -106,8 +106,6 @@ class HearingAidTransport
}
}
- void SinkMetadataChanged(const sink_metadata_t&) override {}
-
void ResetPresentationPosition() override {
VLOG(2) << __func__ << ": called.";
remote_delay_report_ms_ = 0;
diff --git a/system/audio_hal_interface/hidl/le_audio_software_hidl.cc b/system/audio_hal_interface/hidl/le_audio_software_hidl.cc
index d2286ad13e..a87b5c26bc 100644
--- a/system/audio_hal_interface/hidl/le_audio_software_hidl.cc
+++ b/system/audio_hal_interface/hidl/le_audio_software_hidl.cc
@@ -19,12 +19,6 @@
#include "le_audio_software_hidl.h"
-#include <unordered_map>
-#include <vector>
-
-#include "codec_status_hidl.h"
-#include "hal_version_manager.h"
-
namespace bluetooth {
namespace audio {
namespace hidl {
@@ -32,20 +26,10 @@ namespace le_audio {
using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
-using ::android::hardware::bluetooth::audio::V2_1::CodecType;
-using ::android::hardware::bluetooth::audio::V2_1::Lc3FrameDuration;
-using ::android::hardware::bluetooth::audio::V2_1::Lc3Parameters;
-using ::android::hardware::bluetooth::audio::V2_2::AudioLocation;
+using ::android::hardware::bluetooth::audio::V2_0::CodecType;
using ::bluetooth::audio::hidl::SampleRate_2_1;
using ::bluetooth::audio::hidl::SessionType;
using ::bluetooth::audio::hidl::SessionType_2_1;
-using AudioCapabilities_2_2 =
- ::android::hardware::bluetooth::audio::V2_2::AudioCapabilities;
-using ::android::hardware::bluetooth::audio::V2_2::LeAudioMode;
-using ::android::hardware::bluetooth::audio::V2_2::UnicastConfig;
-using ::android::hardware::bluetooth::audio::V2_2::UnicastStreamMap;
-using ::le_audio::set_configurations::SetConfiguration;
-using ::le_audio::types::LeAudioLc3Config;
using ::bluetooth::audio::le_audio::LeAudioClientInterface;
@@ -102,46 +86,6 @@ static ChannelMode le_audio_channel_mode2audio_hal(uint8_t channels_count) {
return ChannelMode::UNKNOWN;
}
-static Lc3FrameDuration le_audio_frame_duration2audio_hal(
- uint8_t frame_duration) {
- switch (frame_duration) {
- case 10000:
- return Lc3FrameDuration::DURATION_10000US;
- case 7500:
- return Lc3FrameDuration::DURATION_7500US;
- }
- // TODO: handle error in the aidl version
- return Lc3FrameDuration::DURATION_10000US;
-}
-
-AudioConfiguration_2_2 offload_config_to_hal_audio_config(
- const ::le_audio::offload_config& offload_config) {
- AudioConfiguration_2_2 audio_config;
- std::vector<UnicastStreamMap> unicast_map;
- for (auto& [handle, location] : offload_config.stream_map) {
- UnicastStreamMap stream = {.streamHandle = handle,
- .audioChannelAllocation = location};
- unicast_map.emplace_back(stream);
- }
- hidl_vec<UnicastStreamMap> hal_map;
- hal_map.setToExternal(unicast_map.data(), unicast_map.size());
- LeAudioConfiguration le_audio_config;
- le_audio_config.mode = LeAudioMode::UNICAST;
- le_audio_config.config.unicastConfig() = {
- .streamMap = std::move(hal_map),
- .peerDelay = offload_config.peer_delay,
- .lc3Config = {.pcmBitDepth = le_audio_bits_per_sample2audio_hal(
- offload_config.bits_per_sample),
- .samplingFrequency = le_audio_sample_rate2audio_hal(
- offload_config.sampling_rate),
- .frameDuration = le_audio_frame_duration2audio_hal(
- offload_config.frame_duration),
- .octetsPerFrame = offload_config.octets_per_frame,
- .blocksPerSdu = offload_config.blocks_per_sdu}};
- audio_config.leAudioConfig(le_audio_config);
- return audio_config;
-}
-
bool is_source_hal_enabled() {
return LeAudioSourceTransport::interface != nullptr;
}
@@ -218,19 +162,6 @@ void LeAudioTransport::MetadataChanged(
stream_cb_.on_metadata_update_(source_metadata);
}
-void LeAudioTransport::SinkMetadataChanged(
- const sink_metadata_t& sink_metadata) {
- auto track_count = sink_metadata.track_count;
-
- if (track_count == 0) {
- LOG(WARNING) << ", invalid number of metadata changed tracks";
- return;
- }
-
- if (stream_cb_.on_sink_metadata_update_)
- stream_cb_.on_sink_metadata_update_(sink_metadata);
-}
-
void LeAudioTransport::ResetPresentationPosition() {
VLOG(2) << __func__ << ": called.";
remote_delay_report_ms_ = 0;
@@ -279,8 +210,7 @@ void flush_sink() {
LeAudioSinkTransport::LeAudioSinkTransport(SessionType_2_1 session_type,
StreamCallbacks stream_cb)
- : IBluetoothSinkTransportInstance(session_type,
- (AudioConfiguration_2_2){}) {
+ : IBluetoothSinkTransportInstance(session_type, {}) {
transport_ =
new LeAudioTransport(flush_sink, std::move(stream_cb),
{SampleRate_2_1::RATE_16000, ChannelMode::STEREO,
@@ -311,11 +241,6 @@ void LeAudioSinkTransport::MetadataChanged(
transport_->MetadataChanged(source_metadata);
}
-void LeAudioSinkTransport::SinkMetadataChanged(
- const sink_metadata_t& sink_metadata) {
- transport_->SinkMetadataChanged(sink_metadata);
-}
-
void LeAudioSinkTransport::ResetPresentationPosition() {
transport_->ResetPresentationPosition();
}
@@ -354,8 +279,7 @@ void flush_source() {
LeAudioSourceTransport::LeAudioSourceTransport(SessionType_2_1 session_type,
StreamCallbacks stream_cb)
- : IBluetoothSourceTransportInstance(session_type,
- (AudioConfiguration_2_2){}) {
+ : IBluetoothSourceTransportInstance(session_type, {}) {
transport_ =
new LeAudioTransport(flush_source, std::move(stream_cb),
{SampleRate_2_1::RATE_16000, ChannelMode::MONO,
@@ -386,11 +310,6 @@ void LeAudioSourceTransport::MetadataChanged(
transport_->MetadataChanged(source_metadata);
}
-void LeAudioSourceTransport::SinkMetadataChanged(
- const sink_metadata_t& sink_metadata) {
- transport_->SinkMetadataChanged(sink_metadata);
-}
-
void LeAudioSourceTransport::ResetPresentationPosition() {
transport_->ResetPresentationPosition();
}
@@ -421,139 +340,6 @@ void LeAudioSourceTransport::ClearPendingStartStream(void) {
transport_->ClearPendingStartStream();
}
-std::unordered_map<SampleRate_2_1, uint8_t> sampling_freq_map{
- {SampleRate_2_1::RATE_8000,
- ::le_audio::codec_spec_conf::kLeAudioSamplingFreq8000Hz},
- {SampleRate_2_1::RATE_16000,
- ::le_audio::codec_spec_conf::kLeAudioSamplingFreq16000Hz},
- {SampleRate_2_1::RATE_24000,
- ::le_audio::codec_spec_conf::kLeAudioSamplingFreq24000Hz},
- {SampleRate_2_1::RATE_32000,
- ::le_audio::codec_spec_conf::kLeAudioSamplingFreq32000Hz},
- {SampleRate_2_1::RATE_44100,
- ::le_audio::codec_spec_conf::kLeAudioSamplingFreq44100Hz},
- {SampleRate_2_1::RATE_48000,
- ::le_audio::codec_spec_conf::kLeAudioSamplingFreq48000Hz},
- {SampleRate_2_1::RATE_88200,
- ::le_audio::codec_spec_conf::kLeAudioSamplingFreq88200Hz},
- {SampleRate_2_1::RATE_96000,
- ::le_audio::codec_spec_conf::kLeAudioSamplingFreq96000Hz},
- {SampleRate_2_1::RATE_176400,
- ::le_audio::codec_spec_conf::kLeAudioSamplingFreq176400Hz},
- {SampleRate_2_1::RATE_192000,
- ::le_audio::codec_spec_conf::kLeAudioSamplingFreq192000Hz}};
-
-std::unordered_map<Lc3FrameDuration, uint8_t> frame_duration_map{
- {Lc3FrameDuration::DURATION_7500US,
- ::le_audio::codec_spec_conf::kLeAudioCodecLC3FrameDur7500us},
- {Lc3FrameDuration::DURATION_10000US,
- ::le_audio::codec_spec_conf::kLeAudioCodecLC3FrameDur10000us}};
-
-std::unordered_map<uint32_t, uint16_t> octets_per_frame_map{
- {30, ::le_audio::codec_spec_conf::kLeAudioCodecLC3FrameLen30},
- {40, ::le_audio::codec_spec_conf::kLeAudioCodecLC3FrameLen40},
- {120, ::le_audio::codec_spec_conf::kLeAudioCodecLC3FrameLen120}};
-
-std::unordered_map<AudioLocation, uint32_t> audio_location_map{
- {AudioLocation::UNKNOWN,
- ::le_audio::codec_spec_conf::kLeAudioLocationMonoUnspecified},
- {AudioLocation::FRONT_LEFT,
- ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft},
- {AudioLocation::FRONT_RIGHT,
- ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight},
- {static_cast<AudioLocation>(AudioLocation::FRONT_LEFT |
- AudioLocation::FRONT_RIGHT),
- ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft |
- ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight}};
-
-bool halConfigToCodecCapabilitySetting(
- UnicastCapability halConfig, CodecCapabilitySetting& codecCapability) {
- if (halConfig.codecType != CodecType::LC3) {
- LOG(WARNING) << "Unsupported codecType: " << toString(halConfig.codecType);
- return false;
- }
-
- Lc3Parameters halLc3Config = halConfig.capabilities;
- AudioLocation supportedChannel = halConfig.supportedChannel;
-
- if (sampling_freq_map.find(halLc3Config.samplingFrequency) ==
- sampling_freq_map.end() ||
- frame_duration_map.find(halLc3Config.frameDuration) ==
- frame_duration_map.end() ||
- octets_per_frame_map.find(halLc3Config.octetsPerFrame) ==
- octets_per_frame_map.end() ||
- audio_location_map.find(supportedChannel) == audio_location_map.end()) {
- LOG(ERROR) << __func__ << ": Failed to convert HAL format to stack format"
- << "\nsample rate = " << (uint8_t)halLc3Config.samplingFrequency
- << "\nframe duration = " << (uint8_t)halLc3Config.frameDuration
- << "\noctets per frame= " << halLc3Config.octetsPerFrame
- << "\naudio location = " << (uint8_t)supportedChannel;
-
- return false;
- }
-
- codecCapability = {
- .id = ::le_audio::set_configurations::LeAudioCodecIdLc3,
- .config = LeAudioLc3Config(
- {.sampling_frequency =
- sampling_freq_map[halLc3Config.samplingFrequency],
- .frame_duration = frame_duration_map[halLc3Config.frameDuration],
- .octets_per_codec_frame =
- octets_per_frame_map[halLc3Config.octetsPerFrame],
- .audio_channel_allocation = audio_location_map[supportedChannel]})};
-
- return true;
-}
-
-std::vector<AudioSetConfiguration> get_offload_capabilities() {
- LOG(INFO) << __func__;
- std::vector<AudioSetConfiguration> offload_capabilities;
- std::vector<AudioCapabilities_2_2> le_audio_hal_capabilities =
- BluetoothAudioSinkClientInterface::GetAudioCapabilities_2_2(
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
- std::string strCapabilityLog;
-
- for (auto halCapability : le_audio_hal_capabilities) {
- CodecCapabilitySetting encodeCapability;
- CodecCapabilitySetting decodeCapability;
- UnicastCapability halEncodeConfig =
- halCapability.leAudioCapabilities().unicastEncodeCapability;
- UnicastCapability halDecodeConfig =
- halCapability.leAudioCapabilities().unicastDecodeCapability;
- AudioSetConfiguration audioSetConfig = {.name = "offload capability"};
- strCapabilityLog.clear();
-
- if (halConfigToCodecCapabilitySetting(halEncodeConfig, encodeCapability)) {
- audioSetConfig.confs.push_back(SetConfiguration(
- ::le_audio::types::kLeAudioDirectionSink, halEncodeConfig.deviceCount,
- halEncodeConfig.deviceCount * halEncodeConfig.channelCountPerDevice,
- encodeCapability));
- strCapabilityLog = " Encode Capability: " + toString(halEncodeConfig);
- }
-
- if (halConfigToCodecCapabilitySetting(halDecodeConfig, decodeCapability)) {
- audioSetConfig.confs.push_back(SetConfiguration(
- ::le_audio::types::kLeAudioDirectionSource,
- halDecodeConfig.deviceCount,
- halDecodeConfig.deviceCount * halDecodeConfig.channelCountPerDevice,
- decodeCapability));
- strCapabilityLog += " Decode Capability: " + toString(halDecodeConfig);
- }
-
- if (!audioSetConfig.confs.empty()) {
- offload_capabilities.push_back(audioSetConfig);
- LOG(INFO) << __func__
- << ": Supported codec capability =" << strCapabilityLog;
-
- } else {
- LOG(INFO) << __func__
- << ": Unknown codec capability =" << toString(halCapability);
- }
- }
-
- return offload_capabilities;
-}
-
} // namespace le_audio
} // namespace hidl
} // namespace audio
diff --git a/system/audio_hal_interface/hidl/le_audio_software_hidl.h b/system/audio_hal_interface/hidl/le_audio_software_hidl.h
index 3a161a619a..3b63c07b3c 100644
--- a/system/audio_hal_interface/hidl/le_audio_software_hidl.h
+++ b/system/audio_hal_interface/hidl/le_audio_software_hidl.h
@@ -26,9 +26,6 @@ namespace hidl {
namespace le_audio {
using ::android::hardware::bluetooth::audio::V2_1::PcmParameters;
-using ::android::hardware::bluetooth::audio::V2_2::LeAudioConfiguration;
-using ::android::hardware::bluetooth::audio::V2_2::UnicastCapability;
-using ::bluetooth::audio::hidl::AudioConfiguration_2_2;
using ::bluetooth::audio::hidl::BluetoothAudioCtrlAck;
using ::le_audio::set_configurations::AudioSetConfiguration;
using ::le_audio::set_configurations::CodecCapabilitySetting;
@@ -51,15 +48,9 @@ using ::bluetooth::audio::le_audio::StreamCallbacks;
void flush_sink();
void flush_source();
-bool halConfigToCodecCapabilitySetting(UnicastCapability halConfig,
- CodecCapabilitySetting& codecCapability);
bool is_source_hal_enabled();
bool is_sink_hal_enabled();
-AudioConfiguration_2_2 offload_config_to_hal_audio_config(
- const ::le_audio::offload_config& offload_config);
-
-std::vector<AudioSetConfiguration> get_offload_capabilities();
class LeAudioTransport {
public:
@@ -78,8 +69,6 @@ class LeAudioTransport {
void MetadataChanged(const source_metadata_t& source_metadata);
- void SinkMetadataChanged(const sink_metadata_t& sink_metadata);
-
void ResetPresentationPosition();
void LogBytesProcessed(size_t bytes_processed);
@@ -125,8 +114,6 @@ class LeAudioSinkTransport
void MetadataChanged(const source_metadata_t& source_metadata) override;
- void SinkMetadataChanged(const sink_metadata_t& sink_metadata) override;
-
void ResetPresentationPosition() override;
void LogBytesRead(size_t bytes_read) override;
@@ -169,8 +156,6 @@ class LeAudioSourceTransport
void MetadataChanged(const source_metadata_t& source_metadata) override;
- void SinkMetadataChanged(const sink_metadata_t& sink_metadata) override;
-
void ResetPresentationPosition() override;
void LogBytesWritten(size_t bytes_written) override;
diff --git a/system/audio_hal_interface/le_audio_software.cc b/system/audio_hal_interface/le_audio_software.cc
index c6a5cc65f9..112ad8f9e7 100644
--- a/system/audio_hal_interface/le_audio_software.cc
+++ b/system/audio_hal_interface/le_audio_software.cc
@@ -38,8 +38,6 @@ namespace {
using ::android::hardware::bluetooth::audio::V2_1::PcmParameters;
using AudioConfiguration_2_1 =
::android::hardware::bluetooth::audio::V2_1::AudioConfiguration;
-using AudioConfiguration_2_2 =
- ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration;
using AudioConfigurationAIDL =
::aidl::android::hardware::bluetooth::audio::AudioConfiguration;
@@ -51,7 +49,7 @@ using ::le_audio::types::CodecLocation;
std::vector<AudioSetConfiguration> get_offload_capabilities() {
if (HalVersionManager::GetHalTransport() ==
BluetoothAudioHalTransport::HIDL) {
- return hidl::le_audio::get_offload_capabilities();
+ return std::vector<AudioSetConfiguration>(0);
}
return aidl::le_audio::get_offload_capabilities();
}
@@ -133,25 +131,6 @@ void LeAudioClientInterface::Sink::StartSession() {
hidl::le_audio::LeAudioSinkTransport::interface->StartSession_2_1();
return;
} else if (HalVersionManager::GetHalVersion() ==
- BluetoothAudioHalVersion::VERSION_2_2) {
- AudioConfiguration_2_2 audio_config;
- if (hidl::le_audio::LeAudioSinkTransport::interface->GetTransportInstance()
- ->GetSessionType_2_1() ==
- hidl::SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
- hidl::le_audio::LeAudioConfiguration le_audio_config = {};
- audio_config.leAudioConfig(le_audio_config);
- } else {
- audio_config.pcmConfig(hidl::le_audio::LeAudioSinkTransport::instance
- ->LeAudioGetSelectedHalPcmConfig());
- }
- if (!hidl::le_audio::LeAudioSinkTransport::interface->UpdateAudioConfig_2_2(
- audio_config)) {
- LOG(ERROR) << __func__ << ": cannot update audio config to HAL";
- return;
- }
- hidl::le_audio::LeAudioSinkTransport::interface->StartSession_2_2();
- return;
- } else if (HalVersionManager::GetHalVersion() ==
BluetoothAudioHalVersion::VERSION_AIDL_V1) {
AudioConfigurationAIDL audio_config;
if (aidl::le_audio::LeAudioSinkTransport::interface->GetTransportInstance()
@@ -236,13 +215,6 @@ void LeAudioClientInterface::Sink::UpdateAudioConfigToHal(
const ::le_audio::offload_config& offload_config) {
if (HalVersionManager::GetHalTransport() ==
BluetoothAudioHalTransport::HIDL) {
- if (hidl::le_audio::LeAudioSinkTransport::interface->GetTransportInstance()
- ->GetSessionType_2_1() !=
- hidl::SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
- return;
- }
- hidl::le_audio::LeAudioSinkTransport::interface->UpdateAudioConfig_2_2(
- hidl::le_audio::offload_config_to_hal_audio_config(offload_config));
return;
}
if (aidl::le_audio::LeAudioSinkTransport::interface->GetTransportInstance()
@@ -330,27 +302,6 @@ void LeAudioClientInterface::Source::StartSession() {
hidl::le_audio::LeAudioSourceTransport::interface->StartSession_2_1();
return;
} else if (HalVersionManager::GetHalVersion() ==
- BluetoothAudioHalVersion::VERSION_2_2) {
- AudioConfiguration_2_2 audio_config;
- if (hidl::le_audio::LeAudioSourceTransport::
- interface->GetTransportInstance()
- ->GetSessionType_2_1() ==
- hidl::SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
- hidl::le_audio::LeAudioConfiguration le_audio_config = {};
- audio_config.leAudioConfig(le_audio_config);
- } else {
- audio_config.pcmConfig(hidl::le_audio::LeAudioSourceTransport::instance
- ->LeAudioGetSelectedHalPcmConfig());
- }
-
- if (!hidl::le_audio::LeAudioSourceTransport::
- interface->UpdateAudioConfig_2_2(audio_config)) {
- LOG(ERROR) << __func__ << ": cannot update audio config to HAL";
- return;
- }
- hidl::le_audio::LeAudioSourceTransport::interface->StartSession_2_2();
- return;
- } else if (HalVersionManager::GetHalVersion() ==
BluetoothAudioHalVersion::VERSION_AIDL_V1) {
AudioConfigurationAIDL audio_config;
if (aidl::le_audio::LeAudioSourceTransport::
@@ -439,16 +390,16 @@ void LeAudioClientInterface::Source::UpdateAudioConfigToHal(
const ::le_audio::offload_config& offload_config) {
if (HalVersionManager::GetHalTransport() ==
BluetoothAudioHalTransport::HIDL) {
- if (hidl::le_audio::LeAudioSourceTransport::
- interface->GetTransportInstance()
- ->GetSessionType_2_1() !=
- hidl::SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
- return;
- }
- hidl::le_audio::LeAudioSourceTransport::interface->UpdateAudioConfig_2_2(
- hidl::le_audio::offload_config_to_hal_audio_config(offload_config));
return;
}
+
+ if (aidl::le_audio::LeAudioSourceTransport::interface->GetTransportInstance()
+ ->GetSessionType() !=
+ aidl::SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+ return;
+ }
+ aidl::le_audio::LeAudioSourceTransport::interface->UpdateAudioConfig(
+ aidl::le_audio::offload_config_to_hal_audio_config(offload_config));
}
size_t LeAudioClientInterface::Source::Write(const uint8_t* p_buf,
@@ -478,11 +429,6 @@ LeAudioClientInterface::Sink* LeAudioClientInterface::GetSink(
BluetoothAudioHalTransport::HIDL) {
hidl::SessionType_2_1 session_type =
hidl::SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH;
- if (CodecManager::GetInstance()->GetCodecLocation() !=
- CodecLocation::HOST) {
- session_type =
- hidl::SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH;
- }
hidl::le_audio::LeAudioSinkTransport::instance =
new hidl::le_audio::LeAudioSinkTransport(session_type,
diff --git a/system/binder/Android.bp b/system/binder/Android.bp
index 0445ea0c00..36802546c5 100644
--- a/system/binder/Android.bp
+++ b/system/binder/Android.bp
@@ -110,6 +110,7 @@ filegroup {
"android/bluetooth/IBluetoothHeadset.aidl",
"android/bluetooth/IBluetoothHearingAid.aidl",
"android/bluetooth/IBluetoothHapClient.aidl",
+ "android/bluetooth/IBluetoothHapClientCallback.aidl",
"android/bluetooth/IBluetoothVolumeControl.aidl",
"android/bluetooth/IBluetoothHidHost.aidl",
"android/bluetooth/IBluetoothLeAudio.aidl",
diff --git a/system/binder/android/bluetooth/IBluetoothHapClient.aidl b/system/binder/android/bluetooth/IBluetoothHapClient.aidl
index 672ab409c6..ee956c3210 100644
--- a/system/binder/android/bluetooth/IBluetoothHapClient.aidl
+++ b/system/binder/android/bluetooth/IBluetoothHapClient.aidl
@@ -18,6 +18,7 @@
package android.bluetooth;
import android.bluetooth.BluetoothDevice;
+import android.bluetooth.IBluetoothHapClientCallback;
import android.content.AttributionSource;
import com.android.modules.utils.SynchronousResultReceiver;
@@ -30,10 +31,6 @@ import com.android.modules.utils.SynchronousResultReceiver;
oneway interface IBluetoothHapClient {
// Public API
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void connect(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void disconnect(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
void getConnectedDevices(in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
void getDevicesMatchingConnectionStates(in int[] states, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
@@ -43,55 +40,46 @@ oneway interface IBluetoothHapClient {
void setConnectionPolicy(in BluetoothDevice device, int connectionPolicy, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
void getConnectionPolicy(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
-
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
void getHapGroup(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
void getActivePresetIndex(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
+ void getActivePresetInfo(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- void selectActivePreset(in BluetoothDevice device, int presetIndex, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
+ oneway void selectPreset(in BluetoothDevice device, int presetIndex, in AttributionSource attributionSource);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- void groupSelectActivePreset(int groupId, int presetIndex, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
+ oneway void selectPresetForGroup(int groupId, int presetIndex, in AttributionSource attributionSource);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- void nextActivePreset(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
+ oneway void switchToNextPreset(in BluetoothDevice device, in AttributionSource attributionSource);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- void groupNextActivePreset(int groupId, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
+ oneway void switchToNextPresetForGroup(int groupId, in AttributionSource attributionSource);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- void previousActivePreset(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
+ oneway void switchToPreviousPreset(in BluetoothDevice device, in AttributionSource attributionSource);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- void groupPreviousActivePreset(int groupId, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
+ oneway void switchToPreviousPresetForGroup(int groupId, in AttributionSource attributionSource);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
void getPresetInfo(in BluetoothDevice device, int presetIndex, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void getAllPresetsInfo(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
+ void getAllPresetInfo(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
void getFeatures(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- void setPresetName(in BluetoothDevice device, int presetIndex, in String name, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
+ oneway void setPresetName(in BluetoothDevice device, int presetIndex, in String name, in AttributionSource attributionSource);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- void groupSetPresetName(int groupId, int presetIndex, in String name, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
+ oneway void setPresetNameForGroup(int groupId, int presetIndex, in String name, in AttributionSource attributionSource);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
+ void registerCallback(in IBluetoothHapClientCallback callback, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
+ void unregisterCallback(in IBluetoothHapClientCallback callback, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
const int PRESET_INDEX_UNAVAILABLE = 0;
const int GROUP_ID_UNAVAILABLE = -1;
- const int STATUS_SET_NAME_NOT_ALLOWED = 1;
- const int STATUS_OPERATION_NOT_SUPPORTED = 2;
- const int STATUS_OPERATION_NOT_POSSIBLE = 3;
- const int STATUS_INVALID_PRESET_NAME_LENGTH = 4;
- const int STATUS_INVALID_PRESET_INDEX = 5;
- const int STATUS_GROUP_OPERATION_NOT_SUPPORTED = 6;
- const int STATUS_PROCEDURE_ALREADY_IN_PROGRESS = 7;
-
const int FEATURE_BIT_NUM_TYPE_MONAURAL = 0;
const int FEATURE_BIT_NUM_TYPE_BANDED = 1;
const int FEATURE_BIT_NUM_SYNCHRONIZATED_PRESETS = 2;
const int FEATURE_BIT_NUM_INDEPENDENT_PRESETS = 3;
const int FEATURE_BIT_NUM_DYNAMIC_PRESETS = 4;
const int FEATURE_BIT_NUM_WRITABLE_PRESETS = 5;
-
- const int PRESET_INFO_REASON_ALL_PRESET_INFO = 0;
- const int PRESET_INFO_REASON_PRESET_INFO_UPDATE = 1;
- const int PRESET_INFO_REASON_PRESET_DELETED = 2;
- const int PRESET_INFO_REASON_PRESET_AVAILABILITY_CHANGED = 3;
- const int PRESET_INFO_REASON_PRESET_INFO_REQUEST_RESPONSE = 4;
}
diff --git a/system/binder/android/bluetooth/IBluetoothHapClientCallback.aidl b/system/binder/android/bluetooth/IBluetoothHapClientCallback.aidl
new file mode 100644
index 0000000000..5e2d8fa30b
--- /dev/null
+++ b/system/binder/android/bluetooth/IBluetoothHapClientCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2022 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.BluetoothHapPresetInfo;
+
+import java.util.List;
+
+/**
+ * Callback definitions for interacting with HAP Client service
+ *
+ * @hide
+ */
+oneway interface IBluetoothHapClientCallback {
+ void onActivePresetChanged(in BluetoothDevice device, in int presetIndex);
+ void onSelectActivePresetFailed(in BluetoothDevice device, in int statusCode);
+ void onSelectActivePresetForGroupFailed(in int hapGroupId, in int statusCode);
+ void onPresetInfoChanged(in BluetoothDevice device,
+ in List<BluetoothHapPresetInfo> presetInfoList,
+ in int statusCode);
+ void onHapFeaturesAvailable(in BluetoothDevice device, in int hapFeatures);
+ void onSetPresetNameFailed(in BluetoothDevice device, in int status);
+ void onSetPresetNameForGroupFailed(in int hapGroupId, in int status);
+}
diff --git a/system/binder/android/bluetooth/IBluetoothHearingAid.aidl b/system/binder/android/bluetooth/IBluetoothHearingAid.aidl
index cb74ffaa5e..92d74f2e79 100644
--- a/system/binder/android/bluetooth/IBluetoothHearingAid.aidl
+++ b/system/binder/android/bluetooth/IBluetoothHearingAid.aidl
@@ -46,7 +46,7 @@ oneway interface IBluetoothHearingAid {
void setConnectionPolicy(in BluetoothDevice device, int connectionPolicy, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
void getConnectionPolicy(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
void setVolume(int volume, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
diff --git a/system/blueberry/facade/topshim/facade.proto b/system/blueberry/facade/topshim/facade.proto
index 0414b77b44..9a8679c525 100644
--- a/system/blueberry/facade/topshim/facade.proto
+++ b/system/blueberry/facade/topshim/facade.proto
@@ -1,11 +1,14 @@
syntax = "proto3";
+import "google/protobuf/empty.proto";
+
package blueberry.facade.topshim;
service AdapterService {
rpc FetchEvents(FetchEventsRequest) returns (stream FetchEventsResponse) {}
rpc ToggleStack(ToggleStackRequest) returns (ToggleStackResponse) {}
rpc SetDiscoveryMode(SetDiscoveryModeRequest) returns (SetDiscoveryModeResponse) {}
+ rpc ClearEventFilter(google.protobuf.Empty) returns (google.protobuf.Empty) {}
}
enum EventType {
diff --git a/system/blueberry/tests/gd/cert/gd_device.py b/system/blueberry/tests/gd/cert/gd_device.py
index 4042e536e8..4674905842 100644
--- a/system/blueberry/tests/gd/cert/gd_device.py
+++ b/system/blueberry/tests/gd/cert/gd_device.py
@@ -15,6 +15,7 @@
# limitations under the License.
from abc import ABC
+from abc import abstractmethod
from datetime import datetime
import inspect
import logging
@@ -22,7 +23,6 @@ import os
import pathlib
import shutil
import signal
-import socket
import subprocess
import time
from typing import List
@@ -141,6 +141,8 @@ class GdDeviceBase(ABC):
"""
WAIT_CHANNEL_READY_TIMEOUT_SECONDS = 10
+ WAIT_SIGINT_TIMEOUT_SECONDS = 5
+ WAIT_SIGKILL_TIMEOUT_SECONDS = 1
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):
@@ -279,16 +281,17 @@ class GdDeviceBase(ABC):
self.grpc_channel.close()
if self.grpc_root_server_port != -1:
self.grpc_root_server_channel.close()
- stop_signal = signal.SIGINT
- self.backing_process.send_signal(stop_signal)
+ stop_signal = self.gracefully_stop_backing_process()
try:
- return_code = self.backing_process.wait(timeout=self.WAIT_CHANNEL_READY_TIMEOUT_SECONDS)
- except subprocess.TimeoutExpired:
+ if stop_signal == 0:
+ raise RuntimeError("Failed to gracefully shutdown backing process")
+ return_code = self.backing_process.wait(timeout=self.WAIT_SIGINT_TIMEOUT_SECONDS)
+ except (subprocess.TimeoutExpired, RuntimeError):
logging.error("[%s] Failed to interrupt backing process via SIGINT, sending SIGKILL" % self.label)
stop_signal = signal.SIGKILL
self.backing_process.kill()
try:
- return_code = self.backing_process.wait(timeout=self.WAIT_CHANNEL_READY_TIMEOUT_SECONDS)
+ return_code = self.backing_process.wait(timeout=self.WAIT_SIGKILL_TIMEOUT_SECONDS)
except subprocess.TimeoutExpired:
logging.error("Failed to kill backing process")
return_code = -65536
@@ -303,6 +306,10 @@ class GdDeviceBase(ABC):
except grpc.FutureTimeoutError:
asserts.fail("[%s] wait channel ready timeout" % self.label)
+ @abstractmethod
+ def gracefully_stop_backing_process(self):
+ return NotImplemented
+
class GdHostOnlyDevice(GdDeviceBase):
"""
@@ -443,12 +450,19 @@ class GdHostOnlyDevice(GdDeviceBase):
logging.warning("[%s] Failed to generated coverage summary, cmd result: %r" % (label, result))
coverage_summary_path.unlink(missing_ok=True)
+ def gracefully_stop_backing_process(self):
+ stop_signal = signal.SIGINT
+ self.backing_process.send_signal(stop_signal)
+ return stop_signal
+
class GdAndroidDevice(GdDeviceBase):
"""Real Android device where the backing process is running on it
"""
WAIT_FOR_DEVICE_TIMEOUT_SECONDS = 180
+ WAIT_FOR_DEVICE_SIGINT_TIMEOUT_SECONDS = 1
+ ADB_ABORT_EXIT_CODE = 134
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):
@@ -542,14 +556,14 @@ class GdAndroidDevice(GdDeviceBase):
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)
+ return_code = self.logcat_process.wait(timeout=self.WAIT_FOR_DEVICE_SIGINT_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)
+ return_code = self.logcat_process.wait(timeout=self.WAIT_SIGKILL_TIMEOUT_SECONDS)
except subprocess.TimeoutExpired:
logging.error("Failed to kill logcat_process %s %s" % (self.label, self.serial_number))
return_code = -65536
@@ -557,29 +571,30 @@ class GdAndroidDevice(GdDeviceBase):
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()
+ self.pull_logs(self.log_path_base)
+
+ def pull_logs(self, base_dir):
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))
+ str(os.path.join(base_dir, "%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))
- ])
+ self.adb.pull(
+ ["/data/misc/bluedroid/bt_config.conf",
+ str(os.path.join(base_dir, "%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))
- ])
+ self.adb.pull(
+ ["/data/misc/bluedroid/bt_config.bak",
+ str(os.path.join(base_dir, "%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):
@@ -787,3 +802,44 @@ class GdAndroidDevice(GdDeviceBase):
pass
time.sleep(5)
asserts.fail(msg='Device %s booting process timed out.' % self.serial_number)
+
+ def gracefully_stop_backing_process(self):
+ """
+ Gracefully stops backing process
+ :return: expected backing process exit code on success, 0 on error
+ """
+ backing_process_pid = None
+ # Since we do not know which segment of self.cmd is the command running
+ # on the Android device. We have to iterate with trial and error.
+ cmd = self.cmd
+ if len(self.cmd) >= 5:
+ # skip adb -s serial shell to speed up the search
+ # we don't know if any environment variables are set up before the
+ # actual command and hence has to try from the 4th argument
+ cmd = self.cmd[4:] + self.cmd[:4]
+ for segment in cmd:
+ try:
+ # pgrep only takes 16 bytes including null terminator
+ # -f cannot be used because that include the full command args
+ current_cmd = pathlib.Path(segment).stem[:15]
+ # -x matches whole command, cannot avoid as short segment may partially match
+ # -n returnes the newest command matched
+ backing_process_pid = int(self.adb.shell("pgrep -n -x {}".format(current_cmd)))
+ logging.debug("Found backing process name on Android as {}, pid is {}".format(
+ segment, backing_process_pid))
+ except (AdbError, ValueError) as e:
+ logging.debug("Failed to run pgrep {}".format(e))
+ if backing_process_pid is not None:
+ break
+ if backing_process_pid is None:
+ logging.warning("Failed to get pid for cmd {}".format(self.cmd))
+ try:
+ logging.debug(self.adb.shell("ps -A | grep bluetooth"))
+ except AdbError:
+ pass
+ return 0
+ stop_signal = signal.SIGINT
+ self.adb.shell("kill -{} {}".format(stop_signal, backing_process_pid))
+ logging.debug("Sent SIGINT to backing process at pid {}".format(backing_process_pid))
+ stop_signal = -self.ADB_ABORT_EXIT_CODE
+ return stop_signal
diff --git a/system/blueberry/tests/gd/rust/topshim/facade/automation_helper.py b/system/blueberry/tests/gd/rust/topshim/facade/automation_helper.py
index 224dffb32a..63e72c58c4 100644
--- a/system/blueberry/tests/gd/rust/topshim/facade/automation_helper.py
+++ b/system/blueberry/tests/gd/rust/topshim/facade/automation_helper.py
@@ -20,6 +20,8 @@ import grpc
from blueberry.facade.topshim import facade_pb2
from blueberry.facade.topshim import facade_pb2_grpc
+from google.protobuf import empty_pb2 as empty_proto
+
class AdapterAutomationHelper():
# Timeout for async wait
@@ -60,6 +62,9 @@ class AdapterAutomationHelper():
async def verify_adapter_started(self):
await asyncio.wait_for(self.pending_future, AdapterAutomationHelper.DEFAULT_TIMEOUT)
+ async def clear_event_filter(self):
+ await self.adapter_stub.ClearEventFilter(empty_proto.Empty())
+
class A2dpAutomationHelper():
"""Invoke gRPC on topshim for A2DP testing"""
diff --git a/system/blueberry/tests/gd/rust/topshim/facade/suspend_test.py b/system/blueberry/tests/gd/rust/topshim/facade/suspend_test.py
new file mode 100644
index 0000000000..d6885bdf31
--- /dev/null
+++ b/system/blueberry/tests/gd/rust/topshim/facade/suspend_test.py
@@ -0,0 +1,42 @@
+#!/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.
+
+import asyncio
+from mobly import test_runner
+from blueberry.tests.gd.rust.topshim.facade import topshim_base_test
+from blueberry.tests.gd.rust.topshim.facade.automation_helper import AdapterAutomationHelper
+import time
+
+
+class SuspendTest(topshim_base_test.TopshimBaseTest):
+
+ async def _test_verify_event_filter_cleared(self):
+ self.dut_adapter = AdapterAutomationHelper(port=self.dut_port)
+ event_loop = asyncio.get_running_loop()
+ self.dut_adapter.fetch_events(event_loop)
+ self.dut_adapter.pending_future = event_loop.create_future()
+ await self.dut_adapter.clear_event_filter()
+ #TODO(optedoblivion): Replace sleep with a call to LeGetRandom and synchronize on
+ # the callback
+ time.sleep(1)
+ self.dut_adapter.event_handler.cancel()
+
+ def test_verify_event_filter_cleared(self):
+ asyncio.run(self._test_verify_event_filter_cleared())
+
+
+if __name__ == "__main__":
+ test_runner.main()
diff --git a/system/blueberry/tests/gd_sl4a/gd_sl4a_device_config.yaml b/system/blueberry/tests/gd_sl4a/gd_sl4a_device_config.yaml
new file mode 100644
index 0000000000..19829b8f72
--- /dev/null
+++ b/system/blueberry/tests/gd_sl4a/gd_sl4a_device_config.yaml
@@ -0,0 +1,35 @@
+_description: Bluetooth cert testing with SL4A
+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)"
+ AndroidDevice:
+ - label: dut
+ # Preferred client port number on the PC host side for SL4A
+ client_port: '8895'
+ # Preferred server port number forwarded from Android to the host PC
+ # via adb for SL4A connections
+ forwarded_port: '8899'
+ # Preferred server port used by SL4A on Android device
+ server_port: '8899'
+ serial: 'DUT'
+logpath: "/tmp/logs" \ No newline at end of file
diff --git a/system/blueberry/tests/gd_sl4a/gd_sl4a_test_runner.py b/system/blueberry/tests/gd_sl4a/gd_sl4a_test_runner.py
new file mode 100644
index 0000000000..2aab47f39e
--- /dev/null
+++ b/system/blueberry/tests/gd_sl4a/gd_sl4a_test_runner.py
@@ -0,0 +1,62 @@
+#!/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_sl4a.hci.le_advanced_scanning_test import LeAdvancedScanningTest
+
+from mobly import suite_runner
+import argparse
+
+ALL_TESTS = [LeAdvancedScanningTest]
+
+
+def main():
+ """
+ Local test runner that allows to specify list of tests to and customize
+ test config file location
+ """
+ parser = argparse.ArgumentParser(description="Run local GD SL4A tests.")
+ parser.add_argument(
+ '-c', '--config', type=str, required=True, metavar='<PATH>', help='Path to the test configuration file.')
+ parser.add_argument(
+ '--tests',
+ '--test_case',
+ nargs='+',
+ type=str,
+ metavar='[ClassA[.test_a] ClassB[.test_b] ...]',
+ help='A list of test classes and optional tests to execute.')
+ parser.add_argument("--all_tests", "-A", type=bool, dest="all_tests", default=False, nargs="?")
+ parser.add_argument("--presubmit", type=bool, dest="presubmit", default=False, nargs="?")
+ parser.add_argument("--postsubmit", type=bool, dest="postsubmit", default=False, nargs="?")
+ args = parser.parse_args()
+ test_list = ALL_TESTS
+ if args.all_tests:
+ test_list = ALL_TESTS
+ elif args.presubmit:
+ test_list = ALL_TESTS
+ elif args.postsubmit:
+ test_list = ALL_TESTS
+ # Do not pass this layer's cmd line argument to next layer
+ argv = ["--config", args.config]
+ if args.tests:
+ argv.append("--tests")
+ for test in args.tests:
+ argv.append(test)
+
+ suite_runner.run_suite(test_list, argv=argv)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/system/blueberry/tests/gd_sl4a/hci/le_advanced_scanning_test.py b/system/blueberry/tests/gd_sl4a/hci/le_advanced_scanning_test.py
new file mode 100644
index 0000000000..ed22e1a8e5
--- /dev/null
+++ b/system/blueberry/tests/gd_sl4a/hci/le_advanced_scanning_test.py
@@ -0,0 +1,249 @@
+#!/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.
+
+import queue
+import logging
+
+from google.protobuf import empty_pb2 as empty_proto
+
+from bluetooth_packets_python3 import hci_packets
+from blueberry.tests.gd_sl4a.lib.bt_constants import ble_scan_settings_modes, ble_address_types, scan_result, ble_scan_settings_phys
+from blueberry.tests.gd_sl4a.lib.ble_lib import generate_ble_scan_objects
+from blueberry.tests.gd_sl4a.lib.gd_sl4a_base_test import GdSl4aBaseTestClass
+from blueberry.facade.hci import le_advertising_manager_facade_pb2 as le_advertising_facade
+from blueberry.facade.hci import le_initiator_address_facade_pb2 as le_initiator_address_facade
+from blueberry.facade import common_pb2 as common
+
+
+class LeAdvancedScanningTest(GdSl4aBaseTestClass):
+
+ def setup_class(self):
+ super().setup_class(cert_module='HCI_INTERFACES')
+ self.default_timeout = 10 # seconds
+
+ def setup_test(self):
+ super().setup_test()
+
+ def teardown_test(self):
+ super().teardown_test()
+
+ def set_cert_privacy_policy_with_random_address(self, random_address):
+ private_policy = le_initiator_address_facade.PrivacyPolicy(
+ address_policy=le_initiator_address_facade.AddressPolicy.USE_STATIC_ADDRESS,
+ address_with_type=common.BluetoothAddressWithType(
+ address=common.BluetoothAddress(address=bytes(random_address, encoding='utf8')),
+ type=common.RANDOM_DEVICE_ADDRESS))
+ self.cert.hci_le_initiator_address.SetPrivacyPolicyForInitiatorAddress(private_policy)
+
+ def set_cert_privacy_policy_with_public_address(self):
+ public_address_bytes = self.cert.hci_controller.GetMacAddress(empty_proto.Empty()).address
+ private_policy = le_initiator_address_facade.PrivacyPolicy(
+ address_policy=le_initiator_address_facade.AddressPolicy.USE_PUBLIC_ADDRESS,
+ address_with_type=common.BluetoothAddressWithType(
+ address=common.BluetoothAddress(address=public_address_bytes), type=common.PUBLIC_DEVICE_ADDRESS))
+ self.cert.hci_le_initiator_address.SetPrivacyPolicyForInitiatorAddress(private_policy)
+ # Bluetooth MAC address must be upper case
+ return public_address_bytes.decode('utf-8').upper()
+
+ def test_scan_filter_device_name_legacy_pdu(self):
+ # Use public address on cert side
+ logging.info("Setting public address")
+ DEVICE_NAME = 'Im_The_CERT!'
+ public_address = self.set_cert_privacy_policy_with_public_address()
+ logging.info("Set public address")
+
+ # Setup cert side to advertise
+ gap_name = hci_packets.GapData()
+ gap_name.data_type = hci_packets.GapDataType.COMPLETE_LOCAL_NAME
+ gap_name.data = list(bytes(DEVICE_NAME, encoding='utf8'))
+ gap_data = le_advertising_facade.GapDataMsg(data=bytes(gap_name.Serialize()))
+ config = le_advertising_facade.AdvertisingConfig(
+ advertisement=[gap_data],
+ interval_min=512,
+ interval_max=768,
+ advertising_type=le_advertising_facade.AdvertisingEventType.ADV_IND,
+ own_address_type=common.USE_PUBLIC_DEVICE_ADDRESS,
+ channel_map=7,
+ filter_policy=le_advertising_facade.AdvertisingFilterPolicy.ALL_DEVICES,
+ tx_power=20)
+ request = le_advertising_facade.CreateAdvertiserRequest(config=config)
+ logging.info("Creating advertiser")
+ create_response = self.cert.hci_le_advertising_manager.CreateAdvertiser(request)
+ logging.info("Created advertiser")
+
+ # Setup SL4A DUT side to scan
+ logging.info("Start scanning with public address %s" % public_address)
+ self.dut.sl4a.bleSetScanSettingsScanMode(ble_scan_settings_modes['low_latency'])
+ filter_list, scan_settings, scan_callback = generate_ble_scan_objects(self.dut.sl4a)
+ expected_event_name = scan_result.format(scan_callback)
+
+ # Setup SL4A DUT filter
+ self.dut.sl4a.bleSetScanFilterDeviceName(DEVICE_NAME)
+ self.dut.sl4a.bleBuildScanFilter(filter_list)
+
+ # Start scanning on SL4A DUT side
+ self.dut.sl4a.bleStartBleScan(filter_list, scan_settings, scan_callback)
+ logging.info("Started scanning")
+ try:
+ # Verify if there is scan result
+ event_info = self.dut.ed.pop_event(expected_event_name, self.default_timeout)
+ except queue.Empty as error:
+ logging.error("Could not find initial advertisement.")
+ return False
+ # Print out scan result
+ mac_address = event_info['data']['Result']['deviceInfo']['address']
+ logging.info("Filter advertisement with address {}".format(mac_address))
+
+ # Stop scanning
+ logging.info("Stop scanning")
+ self.dut.sl4a.bleStopBleScan(scan_callback)
+ logging.info("Stopped scanning")
+
+ # Stop advertising
+ logging.info("Stop advertising")
+ remove_request = le_advertising_facade.RemoveAdvertiserRequest(advertiser_id=create_response.advertiser_id)
+ self.cert.hci_le_advertising_manager.RemoveAdvertiser(remove_request)
+ logging.info("Stopped advertising")
+
+ return True
+
+ def test_scan_filter_device_random_address_legacy_pdu(self):
+ # Use random address on cert side
+ logging.info("Setting random address")
+ RANDOM_ADDRESS = 'D0:05:04:03:02:01'
+ DEVICE_NAME = 'Im_The_CERT!'
+ self.set_cert_privacy_policy_with_random_address(RANDOM_ADDRESS)
+ logging.info("Set random address")
+
+ # Setup cert side to advertise
+ gap_name = hci_packets.GapData()
+ gap_name.data_type = hci_packets.GapDataType.COMPLETE_LOCAL_NAME
+ gap_name.data = list(bytes(DEVICE_NAME, encoding='utf8'))
+ gap_data = le_advertising_facade.GapDataMsg(data=bytes(gap_name.Serialize()))
+ config = le_advertising_facade.AdvertisingConfig(
+ advertisement=[gap_data],
+ interval_min=512,
+ interval_max=768,
+ advertising_type=le_advertising_facade.AdvertisingEventType.ADV_IND,
+ own_address_type=common.USE_RANDOM_DEVICE_ADDRESS,
+ channel_map=7,
+ filter_policy=le_advertising_facade.AdvertisingFilterPolicy.ALL_DEVICES)
+ request = le_advertising_facade.CreateAdvertiserRequest(config=config)
+ logging.info("Creating advertiser")
+ create_response = self.cert.hci_le_advertising_manager.CreateAdvertiser(request)
+ logging.info("Created advertiser")
+
+ # Setup SL4A DUT side to scan
+ addr_type = ble_address_types["random"]
+ logging.info("Start scanning for RANDOM_ADDRESS %s with address type %d" % (RANDOM_ADDRESS, addr_type))
+ self.dut.sl4a.bleSetScanSettingsScanMode(ble_scan_settings_modes['low_latency'])
+ filter_list, scan_settings, scan_callback = generate_ble_scan_objects(self.dut.sl4a)
+ expected_event_name = scan_result.format(scan_callback)
+
+ # Setup SL4A DUT filter
+ self.dut.sl4a.bleSetScanFilterDeviceAddressAndType(RANDOM_ADDRESS, int(addr_type))
+ self.dut.sl4a.bleBuildScanFilter(filter_list)
+
+ # Start scanning on SL4A DUT side
+ self.dut.sl4a.bleStartBleScan(filter_list, scan_settings, scan_callback)
+ logging.info("Started scanning")
+ try:
+ # Verify if there is scan result
+ event_info = self.dut.ed.pop_event(expected_event_name, self.default_timeout)
+ except queue.Empty as error:
+ logging.error("Could not find initial advertisement.")
+ return False
+ # Print out scan result
+ mac_address = event_info['data']['Result']['deviceInfo']['address']
+ logging.info("Filter advertisement with address {}".format(mac_address))
+
+ # Stop scanning
+ logging.info("Stop scanning")
+ self.dut.sl4a.bleStopBleScan(scan_callback)
+ logging.info("Stopped scanning")
+
+ # Stop advertising
+ logging.info("Stop advertising")
+ remove_request = le_advertising_facade.RemoveAdvertiserRequest(advertiser_id=create_response.advertiser_id)
+ self.cert.hci_le_advertising_manager.RemoveAdvertiser(remove_request)
+ logging.info("Stopped advertising")
+
+ return True
+
+ def test_scan_filter_device_public_address_extended_pdu(self):
+ # Use public address on cert side
+ logging.info("Setting public address")
+ DEVICE_NAME = 'Im_The_CERT!'
+ public_address = self.set_cert_privacy_policy_with_public_address()
+ logging.info("Set public address")
+
+ # Setup cert side to advertise
+ gap_name = hci_packets.GapData()
+ gap_name.data_type = hci_packets.GapDataType.COMPLETE_LOCAL_NAME
+ gap_name.data = list(bytes(DEVICE_NAME, encoding='utf8'))
+ gap_data = le_advertising_facade.GapDataMsg(data=bytes(gap_name.Serialize()))
+ config = le_advertising_facade.AdvertisingConfig(
+ advertisement=[gap_data],
+ interval_min=512,
+ interval_max=768,
+ advertising_type=le_advertising_facade.AdvertisingEventType.ADV_IND,
+ own_address_type=common.USE_PUBLIC_DEVICE_ADDRESS,
+ channel_map=7,
+ filter_policy=le_advertising_facade.AdvertisingFilterPolicy.ALL_DEVICES)
+ extended_config = le_advertising_facade.ExtendedAdvertisingConfig(
+ advertising_config=config, secondary_advertising_phy=ble_scan_settings_phys["1m"])
+ request = le_advertising_facade.ExtendedCreateAdvertiserRequest(config=extended_config)
+ logging.info("Creating advertiser")
+ create_response = self.cert.hci_le_advertising_manager.ExtendedCreateAdvertiser(request)
+ logging.info("Created advertiser")
+
+ # Setup SL4A DUT side to scan
+ addr_type = ble_address_types["public"]
+ logging.info("Start scanning for PUBLIC_ADDRESS %s with address type %d" % (public_address, addr_type))
+ self.dut.sl4a.bleSetScanSettingsScanMode(ble_scan_settings_modes['low_latency'])
+ self.dut.sl4a.bleSetScanSettingsLegacy(False)
+ filter_list, scan_settings, scan_callback = generate_ble_scan_objects(self.dut.sl4a)
+ expected_event_name = scan_result.format(scan_callback)
+
+ # Setup SL4A DUT filter
+ self.dut.sl4a.bleSetScanFilterDeviceAddressAndType(public_address, int(addr_type))
+ self.dut.sl4a.bleBuildScanFilter(filter_list)
+
+ # Start scanning on SL4A DUT side
+ self.dut.sl4a.bleStartBleScan(filter_list, scan_settings, scan_callback)
+ logging.info("Started scanning")
+ try:
+ # Verify if there is scan result
+ event_info = self.dut.ed.pop_event(expected_event_name, self.default_timeout)
+ except queue.Empty as error:
+ logging.error("Could not find initial advertisement.")
+ return False
+ # Print out scan result
+ mac_address = event_info['data']['Result']['deviceInfo']['address']
+ logging.info("Filter advertisement with address {}".format(mac_address))
+
+ # Stop scanning
+ logging.info("Stop scanning")
+ self.dut.sl4a.bleStopBleScan(scan_callback)
+ logging.info("Stopped scanning")
+
+ # Stop advertising
+ logging.info("Stop advertising")
+ remove_request = le_advertising_facade.RemoveAdvertiserRequest(advertiser_id=create_response.advertiser_id)
+ self.cert.hci_le_advertising_manager.RemoveAdvertiser(remove_request)
+ logging.info("Stopped advertising")
+
+ return True
diff --git a/system/blueberry/tests/gd_sl4a/lib/ble_lib.py b/system/blueberry/tests/gd_sl4a/lib/ble_lib.py
new file mode 100644
index 0000000000..93b3eaece2
--- /dev/null
+++ b/system/blueberry/tests/gd_sl4a/lib/ble_lib.py
@@ -0,0 +1,259 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License. You may obtain a copy of
+# the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations under
+# the License.
+"""
+Ble libraries
+"""
+
+import time
+import queue
+import logging
+
+from blueberry.tests.gd_sl4a.lib.bt_constants import ble_advertise_settings_modes
+from blueberry.tests.gd_sl4a.lib.bt_constants import small_timeout
+from blueberry.tests.gd_sl4a.lib.bt_constants import adv_fail
+from blueberry.tests.gd_sl4a.lib.bt_constants import adv_succ
+from blueberry.tests.gd_sl4a.lib.bt_constants import advertising_set_on_own_address_read
+from blueberry.tests.gd_sl4a.lib.bt_constants import advertising_set_started
+from blueberry.tests.gd_sl4a.lib.bt_constants import bluetooth_on
+from blueberry.tests.gd_sl4a.lib.bt_constants import bluetooth_off
+from blueberry.tests.gd_sl4a.lib.bt_constants import bt_default_timeout
+
+
+def enable_bluetooth(sl4a, ed):
+ if sl4a.bluetoothCheckState():
+ return True
+
+ sl4a.bluetoothToggleState(True)
+ expected_bluetooth_on_event_name = bluetooth_on
+ try:
+ ed.pop_event(expected_bluetooth_on_event_name, bt_default_timeout)
+ except Exception:
+ logging.info("Failed to toggle Bluetooth on (no broadcast received)")
+ if sl4a.bluetoothCheckState():
+ logging.info(".. actual state is ON")
+ return True
+ logging.info(".. actual state is OFF")
+ return False
+
+ return True
+
+
+def disable_bluetooth(sl4a, ed):
+ if not sl4a.bluetoothCheckState():
+ return True
+ sl4a.bluetoothToggleState(False)
+ expected_bluetooth_off_event_name = bluetooth_off
+ try:
+ ed.pop_event(expected_bluetooth_off_event_name, bt_default_timeout)
+ except Exception:
+ logging.info("Failed to toggle Bluetooth off (no broadcast received)")
+ if sl4a.bluetoothCheckState():
+ logging.info(".. actual state is ON")
+ return False
+ logging.info(".. actual state is OFF")
+ return True
+ return True
+
+
+def generate_ble_scan_objects(sl4a):
+ """Generate generic LE scan objects.
+
+ Args:
+ sl4a: The SL4A object to generate LE scan objects from.
+
+ Returns:
+ filter_list: The generated scan filter list id.
+ scan_settings: The generated scan settings id.
+ scan_callback: The generated scan callback id.
+ """
+ filter_list = sl4a.bleGenFilterList()
+ scan_settings = sl4a.bleBuildScanSetting()
+ scan_callback = sl4a.bleGenScanCallback()
+ return filter_list, scan_settings, scan_callback
+
+
+def generate_ble_advertise_objects(sl4a):
+ """Generate generic LE advertise objects.
+
+ Args:
+ sl4a: The SL4A object to generate advertise LE objects from.
+
+ Returns:
+ advertise_callback: The generated advertise callback id.
+ advertise_data: The generated advertise data id.
+ advertise_settings: The generated advertise settings id.
+ """
+ advertise_callback = sl4a.bleGenBleAdvertiseCallback()
+ advertise_data = sl4a.bleBuildAdvertiseData()
+ advertise_settings = sl4a.bleBuildAdvertiseSettings()
+ return advertise_callback, advertise_data, advertise_settings
+
+
+class BleLib():
+
+ def __init__(self, dut):
+ self.advertisement_list = []
+ self.dut = dut
+ self.default_timeout = 5
+ self.set_advertisement_list = []
+ self.generic_uuid = "0000{}-0000-1000-8000-00805f9b34fb"
+
+ def _verify_ble_adv_started(self, advertise_callback):
+ """Helper for verifying if an advertisment started or not"""
+ regex = "({}|{})".format(adv_succ.format(advertise_callback), adv_fail.format(advertise_callback))
+ try:
+ event = self.dut.ed.pop_events(regex, 5, small_timeout)
+ except queue.Empty:
+ logging.error("Failed to get success or failed event.")
+ return
+ if event[0]["name"] == adv_succ.format(advertise_callback):
+ logging.info("Advertisement started successfully.")
+ return True
+ else:
+ logging.info("Advertisement failed to start.")
+ return False
+
+ def start_generic_connectable_advertisement(self, line):
+ """Start a connectable LE advertisement"""
+ scan_response = None
+ if line:
+ scan_response = bool(line)
+ self.dut.sl4a.bleSetAdvertiseSettingsAdvertiseMode(ble_advertise_settings_modes['low_latency'])
+ self.dut.sl4a.bleSetAdvertiseSettingsIsConnectable(True)
+ advertise_callback, advertise_data, advertise_settings = (generate_ble_advertise_objects(self.dut.sl4a))
+ if scan_response:
+ self.dut.sl4a.bleStartBleAdvertisingWithScanResponse(advertise_callback, advertise_data, advertise_settings,
+ advertise_data)
+ else:
+ self.dut.sl4a.bleStartBleAdvertising(advertise_callback, advertise_data, advertise_settings)
+ if self._verify_ble_adv_started(advertise_callback):
+ logging.info("Tracking Callback ID: {}".format(advertise_callback))
+ self.advertisement_list.append(advertise_callback)
+ logging.info(self.advertisement_list)
+
+ def start_connectable_advertisement_set(self, line):
+ """Start Connectable Advertisement Set"""
+ adv_callback = self.dut.sl4a.bleAdvSetGenCallback()
+ adv_data = {
+ "includeDeviceName": True,
+ }
+ self.dut.sl4a.bleAdvSetStartAdvertisingSet({
+ "connectable": True,
+ "legacyMode": False,
+ "primaryPhy": "PHY_LE_1M",
+ "secondaryPhy": "PHY_LE_1M",
+ "interval": 320
+ }, adv_data, None, None, None, 0, 0, adv_callback)
+ evt = self.dut.ed.pop_event(advertising_set_started.format(adv_callback), self.default_timeout)
+ set_id = evt['data']['setId']
+ logging.error("did not receive the set started event!")
+ evt = self.dut.ed.pop_event(advertising_set_on_own_address_read.format(set_id), self.default_timeout)
+ address = evt['data']['address']
+ logging.info("Advertiser address is: {}".format(str(address)))
+ self.set_advertisement_list.append(adv_callback)
+
+ def stop_all_advertisement_set(self, line):
+ """Stop all Advertisement Sets"""
+ for adv in self.set_advertisement_list:
+ try:
+ self.dut.sl4a.bleAdvSetStopAdvertisingSet(adv)
+ except Exception as err:
+ logging.error("Failed to stop advertisement: {}".format(err))
+
+ def adv_add_service_uuid_list(self, line):
+ """Add service UUID to the LE advertisement inputs:
+ [uuid1 uuid2 ... uuidN]"""
+ uuids = line.split()
+ uuid_list = []
+ for uuid in uuids:
+ if len(uuid) == 4:
+ uuid = self.generic_uuid.format(line)
+ uuid_list.append(uuid)
+ self.dut.sl4a.bleSetAdvertiseDataSetServiceUuids(uuid_list)
+
+ def adv_data_include_local_name(self, is_included):
+ """Include local name in the advertisement. inputs: [true|false]"""
+ self.dut.sl4a.bleSetAdvertiseDataIncludeDeviceName(bool(is_included))
+
+ def adv_data_include_tx_power_level(self, is_included):
+ """Include tx power level in the advertisement. inputs: [true|false]"""
+ self.dut.sl4a.bleSetAdvertiseDataIncludeTxPowerLevel(bool(is_included))
+
+ def adv_data_add_manufacturer_data(self, line):
+ """Include manufacturer id and data to the advertisment:
+ [id data1 data2 ... dataN]"""
+ info = line.split()
+ manu_id = int(info[0])
+ manu_data = []
+ for data in info[1:]:
+ manu_data.append(int(data))
+ self.dut.sl4a.bleAddAdvertiseDataManufacturerId(manu_id, manu_data)
+
+ def start_generic_nonconnectable_advertisement(self, line):
+ """Start a nonconnectable LE advertisement"""
+ self.dut.sl4a.bleSetAdvertiseSettingsAdvertiseMode(ble_advertise_settings_modes['low_latency'])
+ self.dut.sl4a.bleSetAdvertiseSettingsIsConnectable(False)
+ advertise_callback, advertise_data, advertise_settings = (generate_ble_advertise_objects(self.dut.sl4a))
+ self.dut.sl4a.bleStartBleAdvertising(advertise_callback, advertise_data, advertise_settings)
+ if self._verify_ble_adv_started(advertise_callback):
+ logging.info("Tracking Callback ID: {}".format(advertise_callback))
+ self.advertisement_list.append(advertise_callback)
+ logging.info(self.advertisement_list)
+
+ def stop_all_advertisements(self, line):
+ """Stop all LE advertisements"""
+ for callback_id in self.advertisement_list:
+ logging.info("Stopping Advertisement {}".format(callback_id))
+ self.dut.sl4a.bleStopBleAdvertising(callback_id)
+ time.sleep(1)
+ self.advertisement_list = []
+
+ def ble_stop_advertisement(self, callback_id):
+ """Stop an LE advertisement"""
+ if not callback_id:
+ logging.info("Need a callback ID")
+ return
+ callback_id = int(callback_id)
+ if callback_id not in self.advertisement_list:
+ logging.info("Callback not in list of advertisements.")
+ return
+ self.dut.sl4a.bleStopBleAdvertising(callback_id)
+ self.advertisement_list.remove(callback_id)
+
+ def start_max_advertisements(self, line):
+ scan_response = None
+ if line:
+ scan_response = bool(line)
+ while (True):
+ try:
+ self.dut.sl4a.bleSetAdvertiseSettingsAdvertiseMode(ble_advertise_settings_modes['low_latency'])
+ self.dut.sl4a.bleSetAdvertiseSettingsIsConnectable(True)
+ advertise_callback, advertise_data, advertise_settings = (generate_ble_advertise_objects(self.dut.sl4a))
+ if scan_response:
+ self.dut.sl4a.bleStartBleAdvertisingWithScanResponse(advertise_callback, advertise_data,
+ advertise_settings, advertise_data)
+ else:
+ self.dut.sl4a.bleStartBleAdvertising(advertise_callback, advertise_data, advertise_settings)
+ if self._verify_ble_adv_started(advertise_callback):
+ logging.info("Tracking Callback ID: {}".format(advertise_callback))
+ self.advertisement_list.append(advertise_callback)
+ logging.info(self.advertisement_list)
+ else:
+ logging.info("Advertisements active: {}".format(len(self.advertisement_list)))
+ return False
+ except Exception as err:
+ logging.info("Advertisements active: {}".format(len(self.advertisement_list)))
+ return True
diff --git a/system/blueberry/tests/gd_sl4a/lib/bt_constants.py b/system/blueberry/tests/gd_sl4a/lib/bt_constants.py
new file mode 100644
index 0000000000..f144ef57f5
--- /dev/null
+++ b/system/blueberry/tests/gd_sl4a/lib/bt_constants.py
@@ -0,0 +1,740 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License. You may obtain a copy of
+# the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations under
+# the License.
+
+### Generic Constants Begin ###
+
+bt_default_timeout = 15
+default_rfcomm_timeout_ms = 10000
+default_bluetooth_socket_timeout_ms = 10000
+pan_connect_timeout = 5
+bt_discovery_timeout = 3
+small_timeout = 0.0001
+
+# Time delay (in seconds) at the end of each LE CoC Test to give sufficient time
+# for the ACL LE link to be disconnected. The ACL link stays connected after
+# L2CAP disconnects. An example of the timeout is L2CAP_LINK_INACTIVITY_TOUT.
+# This delay must be greater than the maximum of these timeouts.
+# TODO: Investigate the use of broadcast intent
+# BluetoothDevice.ACTION_ACL_DISCONNECTED to replace this delay method.
+l2cap_max_inactivity_delay_after_disconnect = 5
+
+# LE specifications related constants
+le_connection_interval_time_step_ms = 1.25
+le_default_supervision_timeout = 2000
+default_le_data_length = 23
+default_le_connection_interval_ms = 30
+le_connection_event_time_step_ms = 0.625
+
+# Headers of LE L2CAP Connection-oriented Channels. See section 3.4, Vol
+# 3, Part A, Version 5.0.
+l2cap_header_size = 4
+l2cap_coc_sdu_length_field_size = 2
+l2cap_coc_header_size = l2cap_header_size + l2cap_coc_sdu_length_field_size
+
+java_integer = {"min": -2147483648, "max": 2147483647}
+
+btsnoop_log_path_on_device = "/data/misc/bluetooth/logs/btsnoop_hci.log"
+btsnoop_last_log_path_on_device = \
+ "/data/misc/bluetooth/logs/btsnoop_hci.log.last"
+pairing_variant_passkey_confirmation = 2
+
+# Callback strings
+scan_result = "BleScan{}onScanResults"
+scan_failed = "BleScan{}onScanFailed"
+batch_scan_result = "BleScan{}onBatchScanResult"
+adv_fail = "BleAdvertise{}onFailure"
+adv_succ = "BleAdvertise{}onSuccess"
+bluetooth_off = "BluetoothStateChangedOff"
+bluetooth_on = "BluetoothStateChangedOn"
+mtu_changed = "GattConnect{}onMtuChanged"
+advertising_set_started = "AdvertisingSet{}onAdvertisingSetStarted"
+advertising_set_stopped = "AdvertisingSet{}onAdvertisingSetStopped"
+advertising_set_on_own_address_read = "AdvertisingSet{}onOwnAddressRead"
+advertising_set_enabled = "AdvertisingSet{}onAdvertisingEnabled"
+advertising_set_data_set = "AdvertisingSet{}onAdvertisingDataSet"
+advertising_set_scan_response_set = "AdvertisingSet{}onScanResponseDataSet"
+advertising_set_parameters_update = \
+ "AdvertisingSet{}onAdvertisingParametersUpdated"
+advertising_set_periodic_parameters_updated = \
+ "AdvertisingSet{}onPeriodicAdvertisingParametersUpdated"
+advertising_set_periodic_data_set = \
+ "AdvertisingSet{}onPeriodicAdvertisingDataSet"
+advertising_set_periodic_enable = "AdvertisingSet{}onPeriodicAdvertisingEnable"
+bluetooth_profile_connection_state_changed = \
+ "BluetoothProfileConnectionStateChanged"
+bluetooth_le_on = "BleStateChangedOn"
+bluetooth_le_off = "BleStateChangedOff"
+bluetooth_a2dp_codec_config_changed = "BluetoothA2dpCodecConfigChanged"
+# End Callback Strings
+
+batch_scan_not_supported_list = [
+ "Nexus 4",
+ "Nexus 5",
+ "Nexus 7",
+]
+
+### Generic Constants End ###
+
+### Bluetooth Constants Begin ###
+
+# rfcomm test uuids
+rfcomm_secure_uuid = "fa87c0d0-afac-11de-8a39-0800200c9a66"
+rfcomm_insecure_uuid = "8ce255c0-200a-11e0-ac64-0800200c9a66"
+
+# bluetooth socket connection test uuid
+bluetooth_socket_conn_test_uuid = "12345678-1234-5678-9abc-123456789abc"
+
+# Bluetooth Adapter Scan Mode Types
+bt_scan_mode_types = {"state_off": -1, "none": 0, "connectable": 1, "connectable_discoverable": 3}
+
+# Bluetooth Adapter State Constants
+bt_adapter_states = {
+ "off": 10,
+ "turning_on": 11,
+ "on": 12,
+ "turning_off": 13,
+ "ble_turning_on": 14,
+ "ble_on": 15,
+ "ble_turning_off": 16
+}
+
+# Should be kept in sync with BluetoothProfile.java
+bt_profile_constants = {
+ "headset": 1,
+ "a2dp": 2,
+ "health": 3,
+ "input_device": 4,
+ "pan": 5,
+ "pbap_server": 6,
+ "gatt": 7,
+ "gatt_server": 8,
+ "map": 9,
+ "sap": 10,
+ "a2dp_sink": 11,
+ "avrcp_controller": 12,
+ "headset_client": 16,
+ "pbap_client": 17,
+ "map_mce": 18
+}
+
+# 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"
+}
+
+# Should be kept in sync with BluetoothProfile#STATE_* constants.
+bt_profile_states = {"disconnected": 0, "connecting": 1, "connected": 2, "disconnecting": 3}
+
+# Access Levels from BluetoothDevice.
+bt_access_levels = {"access_allowed": 1, "access_denied": 2}
+
+# Priority levels as defined in BluetoothProfile.java.
+bt_priority_levels = {"auto_connect": 1000, "on": 100, "off": 0, "undefined": -1}
+
+# A2DP codec configuration constants as defined in
+# frameworks/base/core/java/android/bluetooth/BluetoothCodecConfig.java
+codec_types = {'SBC': 0, 'AAC': 1, 'APTX': 2, 'APTX-HD': 3, 'LDAC': 4, 'MAX': 5, 'INVALID': 1000000}
+
+codec_priorities = {'DISABLED': -1, 'DEFAULT': 0, 'HIGHEST': 1000000}
+
+sample_rates = {
+ 'NONE': 0,
+ '44100': 0x1 << 0,
+ '48000': 0x1 << 1,
+ '88200': 0x1 << 2,
+ '96000': 0x1 << 3,
+ '176400': 0x1 << 4,
+ '192000': 0x1 << 5
+}
+
+bits_per_samples = {'NONE': 0, '16': 0x1 << 0, '24': 0x1 << 1, '32': 0x1 << 2}
+
+channel_modes = {'NONE': 0, 'MONO': 0x1 << 0, 'STEREO': 0x1 << 1}
+
+# Bluetooth HID constants.
+hid_connection_timeout = 5
+
+# Bluetooth HID EventFacade constants.
+hid_on_set_report_event = "onSetReport"
+hid_on_get_report_event = "onGetReport"
+hid_on_set_protocol_event = "onSetProtocol"
+hid_on_intr_data_event = "onInterruptData"
+hid_on_virtual_cable_unplug_event = "onVirtualCableUnplug"
+hid_id_keyboard = 1
+hid_id_mouse = 2
+hid_default_event_timeout = 15
+hid_default_set_report_payload = "Haha"
+
+### Bluetooth Constants End ###
+
+### Bluetooth Low Energy Constants Begin ###
+
+# Bluetooth Low Energy address types
+ble_address_types = {"public": 0, "random": 1}
+
+# Bluetooth Low Energy scan callback types
+ble_scan_settings_callback_types = {"all_matches": 1, "first_match": 2, "match_lost": 4, "found_and_lost": 6}
+
+# Bluetooth Low Energy scan settings match mode
+ble_scan_settings_match_modes = {"aggresive": 1, "sticky": 2}
+
+# Bluetooth Low Energy scan settings match nums
+ble_scan_settings_match_nums = {"one": 1, "few": 2, "max": 3}
+
+# Bluetooth Low Energy scan settings result types
+ble_scan_settings_result_types = {"full": 0, "abbreviated": 1}
+
+# Bluetooth Low Energy scan settings mode
+ble_scan_settings_modes = {
+ "opportunistic": -1,
+ "low_power": 0,
+ "balanced": 1,
+ "low_latency": 2,
+ "ambient_discovery": 3,
+}
+
+# Bluetooth Low Energy scan settings report delay millis
+ble_scan_settings_report_delay_milli_seconds = {"min": 0, "max": 9223372036854775807}
+
+# Bluetooth Low Energy scan settings phy
+ble_scan_settings_phys = {"1m": 1, "2m": 2, "coded": 3, "all_supported": 255}
+
+# Bluetooth Low Energy advertise settings types
+ble_advertise_settings_types = {"non_connectable": 0, "connectable": 1}
+
+# Bluetooth Low Energy advertise settings modes
+ble_advertise_settings_modes = {"low_power": 0, "balanced": 1, "low_latency": 2}
+
+# Bluetooth Low Energy advertise settings tx power
+ble_advertise_settings_tx_powers = {"ultra_low": 0, "low": 1, "medium": 2, "high": 3}
+
+# Bluetooth Low Energy service uuids for specific devices
+ble_uuids = {"p_service": "0000feef-0000-1000-8000-00805f9b34fb", "hr_service": "0000180d-0000-1000-8000-00805f9b34fb"}
+
+# Bluetooth Low Energy advertising error codes
+ble_advertise_error_code = {
+ "data_too_large": 1,
+ "too_many_advertisers": 2,
+ "advertisement_already_started": 3,
+ "bluetooth_internal_failure": 4,
+ "feature_not_supported": 5
+}
+
+### Bluetooth Low Energy Constants End ###
+
+### Bluetooth GATT Constants Begin ###
+
+# Gatt Callback error messages
+gatt_cb_err = {
+ "char_write_req_err": "Characteristic Write Request event not found. Expected {}",
+ "char_write_err": "Characteristic Write event not found. Expected {}",
+ "desc_write_req_err": "Descriptor Write Request event not found. Expected {}",
+ "desc_write_err": "Descriptor Write event not found. Expected {}",
+ "char_read_err": "Characteristic Read event not found. Expected {}",
+ "char_read_req_err": "Characteristic Read Request not found. Expected {}",
+ "desc_read_err": "Descriptor Read event not found. Expected {}",
+ "desc_read_req_err": "Descriptor Read Request event not found. Expected {}",
+ "rd_remote_rssi_err": "Read Remote RSSI event not found. Expected {}",
+ "gatt_serv_disc_err": "GATT Services Discovered event not found. Expected {}",
+ "serv_added_err": "Service Added event not found. Expected {}",
+ "mtu_changed_err": "MTU Changed event not found. Expected {}",
+ "mtu_serv_changed_err": "MTU Server Changed event not found. Expected {}",
+ "gatt_conn_changed_err": "GATT Connection Changed event not found. Expected {}",
+ "char_change_err": "GATT Characteristic Changed event not fond. Expected {}",
+ "phy_read_err": "Phy Read event not fond. Expected {}",
+ "phy_update_err": "Phy Update event not fond. Expected {}",
+ "exec_write_err": "GATT Execute Write event not found. Expected {}"
+}
+
+# GATT callback strings as defined in GattClientFacade.java and
+# GattServerFacade.java implemented callbacks.
+gatt_cb_strings = {
+ "char_write_req": "GattServer{}onCharacteristicWriteRequest",
+ "exec_write": "GattServer{}onExecuteWrite",
+ "char_write": "GattConnect{}onCharacteristicWrite",
+ "desc_write_req": "GattServer{}onDescriptorWriteRequest",
+ "desc_write": "GattConnect{}onDescriptorWrite",
+ "char_read": "GattConnect{}onCharacteristicRead",
+ "char_read_req": "GattServer{}onCharacteristicReadRequest",
+ "desc_read": "GattConnect{}onDescriptorRead",
+ "desc_read_req": "GattServer{}onDescriptorReadRequest",
+ "rd_remote_rssi": "GattConnect{}onReadRemoteRssi",
+ "gatt_serv_disc": "GattConnect{}onServicesDiscovered",
+ "serv_added": "GattServer{}onServiceAdded",
+ "mtu_changed": "GattConnect{}onMtuChanged",
+ "mtu_serv_changed": "GattServer{}onMtuChanged",
+ "gatt_conn_change": "GattConnect{}onConnectionStateChange",
+ "char_change": "GattConnect{}onCharacteristicChanged",
+ "phy_read": "GattConnect{}onPhyRead",
+ "phy_update": "GattConnect{}onPhyUpdate",
+ "serv_phy_read": "GattServer{}onPhyRead",
+ "serv_phy_update": "GattServer{}onPhyUpdate",
+}
+
+# GATT event dictionary of expected callbacks and errors.
+gatt_event = {
+ "char_write_req": {
+ "evt": gatt_cb_strings["char_write_req"],
+ "err": gatt_cb_err["char_write_req_err"]
+ },
+ "exec_write": {
+ "evt": gatt_cb_strings["exec_write"],
+ "err": gatt_cb_err["exec_write_err"]
+ },
+ "char_write": {
+ "evt": gatt_cb_strings["char_write"],
+ "err": gatt_cb_err["char_write_err"]
+ },
+ "desc_write_req": {
+ "evt": gatt_cb_strings["desc_write_req"],
+ "err": gatt_cb_err["desc_write_req_err"]
+ },
+ "desc_write": {
+ "evt": gatt_cb_strings["desc_write"],
+ "err": gatt_cb_err["desc_write_err"]
+ },
+ "char_read": {
+ "evt": gatt_cb_strings["char_read"],
+ "err": gatt_cb_err["char_read_err"]
+ },
+ "char_read_req": {
+ "evt": gatt_cb_strings["char_read_req"],
+ "err": gatt_cb_err["char_read_req_err"]
+ },
+ "desc_read": {
+ "evt": gatt_cb_strings["desc_read"],
+ "err": gatt_cb_err["desc_read_err"]
+ },
+ "desc_read_req": {
+ "evt": gatt_cb_strings["desc_read_req"],
+ "err": gatt_cb_err["desc_read_req_err"]
+ },
+ "rd_remote_rssi": {
+ "evt": gatt_cb_strings["rd_remote_rssi"],
+ "err": gatt_cb_err["rd_remote_rssi_err"]
+ },
+ "gatt_serv_disc": {
+ "evt": gatt_cb_strings["gatt_serv_disc"],
+ "err": gatt_cb_err["gatt_serv_disc_err"]
+ },
+ "serv_added": {
+ "evt": gatt_cb_strings["serv_added"],
+ "err": gatt_cb_err["serv_added_err"]
+ },
+ "mtu_changed": {
+ "evt": gatt_cb_strings["mtu_changed"],
+ "err": gatt_cb_err["mtu_changed_err"]
+ },
+ "gatt_conn_change": {
+ "evt": gatt_cb_strings["gatt_conn_change"],
+ "err": gatt_cb_err["gatt_conn_changed_err"]
+ },
+ "char_change": {
+ "evt": gatt_cb_strings["char_change"],
+ "err": gatt_cb_err["char_change_err"]
+ },
+ "phy_read": {
+ "evt": gatt_cb_strings["phy_read"],
+ "err": gatt_cb_err["phy_read_err"]
+ },
+ "phy_update": {
+ "evt": gatt_cb_strings["phy_update"],
+ "err": gatt_cb_err["phy_update_err"]
+ },
+ "serv_phy_read": {
+ "evt": gatt_cb_strings["serv_phy_read"],
+ "err": gatt_cb_err["phy_read_err"]
+ },
+ "serv_phy_update": {
+ "evt": gatt_cb_strings["serv_phy_update"],
+ "err": gatt_cb_err["phy_update_err"]
+ }
+}
+
+# Matches constants of connection states defined in BluetoothGatt.java
+gatt_connection_state = {"disconnected": 0, "connecting": 1, "connected": 2, "disconnecting": 3, "closed": 4}
+
+# Matches constants of Bluetooth GATT Characteristic values as defined
+# in BluetoothGattCharacteristic.java
+gatt_characteristic = {
+ "property_broadcast": 0x01,
+ "property_read": 0x02,
+ "property_write_no_response": 0x04,
+ "property_write": 0x08,
+ "property_notify": 0x10,
+ "property_indicate": 0x20,
+ "property_signed_write": 0x40,
+ "property_extended_props": 0x80,
+ "permission_read": 0x01,
+ "permission_read_encrypted": 0x02,
+ "permission_read_encrypted_mitm": 0x04,
+ "permission_write": 0x10,
+ "permission_write_encrypted": 0x20,
+ "permission_write_encrypted_mitm": 0x40,
+ "permission_write_signed": 0x80,
+ "permission_write_signed_mitm": 0x100,
+ "write_type_default": 0x02,
+ "write_type_no_response": 0x01,
+ "write_type_signed": 0x04,
+}
+
+# Matches constants of Bluetooth GATT Characteristic values as defined
+# in BluetoothGattDescriptor.java
+gatt_descriptor = {
+ "enable_notification_value": [0x01, 0x00],
+ "enable_indication_value": [0x02, 0x00],
+ "disable_notification_value": [0x00, 0x00],
+ "permission_read": 0x01,
+ "permission_read_encrypted": 0x02,
+ "permission_read_encrypted_mitm": 0x04,
+ "permission_write": 0x10,
+ "permission_write_encrypted": 0x20,
+ "permission_write_encrypted_mitm": 0x40,
+ "permission_write_signed": 0x80,
+ "permission_write_signed_mitm": 0x100
+}
+
+# https://www.bluetooth.com/specifications/gatt/descriptors
+gatt_char_desc_uuids = {
+ "char_ext_props": '00002900-0000-1000-8000-00805f9b34fb',
+ "char_user_desc": '00002901-0000-1000-8000-00805f9b34fb',
+ "client_char_cfg": '00002902-0000-1000-8000-00805f9b34fb',
+ "server_char_cfg": '00002903-0000-1000-8000-00805f9b34fb',
+ "char_fmt_uuid": '00002904-0000-1000-8000-00805f9b34fb',
+ "char_agreg_fmt": '00002905-0000-1000-8000-00805f9b34fb',
+ "char_valid_range": '00002906-0000-1000-8000-00805f9b34fb',
+ "external_report_reference": '00002907-0000-1000-8000-00805f9b34fb',
+ "report_reference": '00002908-0000-1000-8000-00805f9b34fb'
+}
+
+# https://www.bluetooth.com/specifications/gatt/characteristics
+gatt_char_types = {
+ "device_name": '00002a00-0000-1000-8000-00805f9b34fb',
+ "appearance": '00002a01-0000-1000-8000-00805f9b34fb',
+ "peripheral_priv_flag": '00002a02-0000-1000-8000-00805f9b34fb',
+ "reconnection_address": '00002a03-0000-1000-8000-00805f9b34fb',
+ "peripheral_pref_conn": '00002a04-0000-1000-8000-00805f9b34fb',
+ "service_changed": '00002a05-0000-1000-8000-00805f9b34fb',
+ "system_id": '00002a23-0000-1000-8000-00805f9b34fb',
+ "model_number_string": '00002a24-0000-1000-8000-00805f9b34fb',
+ "serial_number_string": '00002a25-0000-1000-8000-00805f9b34fb',
+ "firmware_revision_string": '00002a26-0000-1000-8000-00805f9b34fb',
+ "hardware_revision_string": '00002a27-0000-1000-8000-00805f9b34fb',
+ "software_revision_string": '00002a28-0000-1000-8000-00805f9b34fb',
+ "manufacturer_name_string": '00002a29-0000-1000-8000-00805f9b34fb',
+ "pnp_id": '00002a50-0000-1000-8000-00805f9b34fb',
+}
+
+# Matches constants of Bluetooth GATT Characteristic values as defined
+# in BluetoothGattCharacteristic.java
+gatt_characteristic_value_format = {
+ "string": 0x1,
+ "byte": 0x2,
+ "sint8": 0x21,
+ "uint8": 0x11,
+ "sint16": 0x22,
+ "unit16": 0x12,
+ "sint32": 0x24,
+ "uint32": 0x14
+}
+
+# Matches constants of Bluetooth Gatt Service types as defined in
+# BluetoothGattService.java
+gatt_service_types = {"primary": 0, "secondary": 1}
+
+# Matches constants of Bluetooth Gatt Connection Priority values as defined in
+# BluetoothGatt.java
+gatt_connection_priority = {"balanced": 0, "high": 1, "low_power": 2}
+
+# Min and max MTU values
+gatt_mtu_size = {"min": 23, "max": 217}
+
+# Gatt Characteristic attribute lengths
+gatt_characteristic_attr_length = {"attr_1": 1, "attr_2": 3, "attr_3": 15}
+
+# Matches constants of Bluetooth Gatt operations status as defined in
+# BluetoothGatt.java
+gatt_status = {"success": 0, "failure": 0x101}
+
+# Matches constants of Bluetooth transport values as defined in
+# BluetoothDevice.java
+gatt_transport = {"auto": 0x00, "bredr": 0x01, "le": 0x02}
+
+# Matches constants of Bluetooth physical channeling values as defined in
+# BluetoothDevice.java
+gatt_phy = {"1m": 1, "2m": 2, "le_coded": 3}
+
+# Matches constants of Bluetooth physical channeling bitmask values as defined
+# in BluetoothDevice.java
+gatt_phy_mask = {"1m_mask": 1, "2m_mask": 2, "coded_mask": 4}
+
+# Values as defiend in the Bluetooth GATT specification
+gatt_server_responses = {
+ "GATT_SUCCESS": 0x0,
+ "GATT_FAILURE": 0x1,
+ "GATT_READ_NOT_PERMITTED": 0x2,
+ "GATT_WRITE_NOT_PERMITTED": 0x3,
+ "GATT_INVALID_PDU": 0x4,
+ "GATT_INSUFFICIENT_AUTHENTICATION": 0x5,
+ "GATT_REQUEST_NOT_SUPPORTED": 0x6,
+ "GATT_INVALID_OFFSET": 0x7,
+ "GATT_INSUFFICIENT_AUTHORIZATION": 0x8,
+ "GATT_INVALID_ATTRIBUTE_LENGTH": 0xd,
+ "GATT_INSUFFICIENT_ENCRYPTION": 0xf,
+ "GATT_CONNECTION_CONGESTED": 0x8f,
+ "GATT_13_ERR": 0x13,
+ "GATT_12_ERR": 0x12,
+ "GATT_0C_ERR": 0x0C,
+ "GATT_16": 0x16
+}
+
+### Bluetooth GATT Constants End ###
+
+### Chameleon Constants Begin ###
+
+# Chameleon audio bits per sample.
+audio_bits_per_sample_16 = 16
+audio_bits_per_sample_24 = 24
+audio_bits_per_sample_32 = 32
+
+# Chameleon audio sample rates.
+audio_sample_rate_44100 = 44100
+audio_sample_rate_48000 = 48000
+audio_sample_rate_88200 = 88200
+audio_sample_rate_96000 = 96000
+
+# Chameleon audio channel modes.
+audio_channel_mode_mono = 1
+audio_channel_mode_stereo = 2
+audio_channel_mode_8 = 8
+
+# Chameleon time delays.
+delay_after_binding_seconds = 0.5
+delay_before_record_seconds = 0.5
+silence_wait_seconds = 5
+
+# Chameleon bus endpoints.
+fpga_linein_bus_endpoint = 'Chameleon FPGA line-in'
+headphone_bus_endpoint = 'Cros device headphone'
+
+### Chameleon Constants End ###
+
+# Begin logcat strings dict"""
+logcat_strings = {
+ "media_playback_vol_changed": "onRouteVolumeChanged",
+}
+
+# End logcat strings dict"""
+
+### Begin Service Discovery UUIDS ###
+# Values match the Bluetooth SIG defined values: """
+""" https://www.bluetooth.com/specifications/assigned-numbers/service-discovery """
+sig_uuid_constants = {
+ "BASE_UUID": "0000{}-0000-1000-8000-00805F9B34FB",
+ "SDP": "0001",
+ "UDP": "0002",
+ "RFCOMM": "0003",
+ "TCP": "0004",
+ "TCS-BIN": "0005",
+ "TCS-AT": "0006",
+ "ATT": "0007",
+ "OBEX": "0008",
+ "IP": "0009",
+ "FTP": "000A",
+ "HTTP": "000C",
+ "WSP": "000E",
+ "BNEP": "000F",
+ "UPNP": "0010",
+ "HIDP": "0011",
+ "HardcopyControlChannel": "0012",
+ "HardcopyDataChannel": "0014",
+ "HardcopyNotification": "0016",
+ "AVCTP": "0017",
+ "AVDTP": "0019",
+ "CMTP": "001B",
+ "MCAPControlChannel": "001E",
+ "MCAPDataChannel": "001F",
+ "L2CAP": "0100",
+ "ServiceDiscoveryServerServiceClassID": "1000",
+ "BrowseGroupDescriptorServiceClassID": "1001",
+ "SerialPort": "1101",
+ "LANAccessUsingPPP": "1102",
+ "DialupNetworking": "1103",
+ "IrMCSync": "1104",
+ "OBEXObjectPush": "1105",
+ "OBEXFileTransfer": "1106",
+ "IrMCSyncCommand": "1107",
+ "Headset": "1108",
+ "CordlessTelephony": "1109",
+ "AudioSource": "110A",
+ "AudioSink": "110B",
+ "A/V_RemoteControlTarget": "110C",
+ "AdvancedAudioDistribution": "110D",
+ "A/V_RemoteControl": "110E",
+ "A/V_RemoteControlController": "110F",
+ "Intercom": "1110",
+ "Fax": "1111",
+ "Headset - Audio Gateway (AG)": "1112",
+ "WAP": "1113",
+ "WAP_CLIENT": "1114",
+ "PANU": "1115",
+ "NAP": "1116",
+ "GN": "1117",
+ "DirectPrinting": "1118",
+ "ReferencePrinting": "1119",
+ "ImagingResponder": "111B",
+ "ImagingAutomaticArchive": "111C",
+ "ImagingReferencedObjects": "111D",
+ "Handsfree": "111E",
+ "HandsfreeAudioGateway": "111F",
+ "DirectPrintingReferenceObjectsService": "1120",
+ "ReflectedUI": "1121",
+ "BasicPrinting": "1122",
+ "PrintingStatus": "1123",
+ "HumanInterfaceDeviceService": "1124",
+ "HardcopyCableReplacement": "1125",
+ "HCR_Print": "1126",
+ "HCR_Scan": "1127",
+ "Common_ISDN_Access": "1128",
+ "SIM_Access": "112D",
+ "Phonebook Access - PCE": "112E",
+ "Phonebook Access - PSE": "112F",
+ "Phonebook Access": "1130",
+ "Headset - HS": "1131",
+ "Message Access Server": "1132",
+ "Message Notification Server": "1133",
+ "Message Access Profile": "1134",
+ "GNSS": "1135",
+ "GNSS_Server": "1136",
+ "PnPInformation": "1200",
+ "GenericNetworking": "1201",
+ "GenericFileTransfer": "1202",
+ "GenericAudio": "1203",
+ "GenericTelephony": "1204",
+ "UPNP_Service": "1205",
+ "UPNP_IP_Service": "1206",
+ "ESDP_UPNP_IP_PAN": "1300",
+ "ESDP_UPNP_IP_LAP": "1301",
+ "ESDP_UPNP_L2CAP": "1302",
+ "VideoSource": "1303",
+ "VideoSink": "1304",
+ "VideoDistribution": "1305",
+ "HDP": "1400"
+}
+
+### End Service Discovery UUIDS ###
+
+### Begin Appearance Constants ###
+# https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.gap.appearance.xml
+sig_appearance_constants = {
+ "UNKNOWN": 0,
+ "PHONE": 64,
+ "COMPUTER": 128,
+ "WATCH": 192,
+ "WATCH_SPORTS": 193,
+ "CLOCK": 256,
+ "DISPLAY": 320,
+ "REMOTE_CONTROL": 384,
+ "EYE_GLASSES": 448,
+ "TAG": 512,
+ "KEYRING": 576,
+ "MEDIA_PLAYER": 640,
+ "BARCODE_SCANNER": 704,
+ "THERMOMETER": 768,
+ "THERMOMETER_EAR": 769,
+ "HEART_RATE_SENSOR": 832,
+ "HEART_RATE_SENSOR_BELT": 833,
+ "BLOOD_PRESSURE": 896,
+ "BLOOD_PRESSURE_ARM": 897,
+ "BLOOD_PRESSURE_WRIST": 898,
+ "HID": 960,
+ "HID_KEYBOARD": 961,
+ "HID_MOUSE": 962,
+ "HID_JOYSTICK": 963,
+ "HID_GAMEPAD": 964,
+ "HID_DIGITIZER_TABLET": 965,
+ "HID_CARD_READER": 966,
+ "HID_DIGITAL_PEN": 967,
+ "HID_BARCODE_SCANNER": 968,
+ "GLUCOSE_METER": 1024,
+ "RUNNING_WALKING_SENSOR": 1088,
+ "RUNNING_WALKING_SENSOR_IN_SHOE": 1089,
+ "RUNNING_WALKING_SENSOR_ON_SHOE": 1090,
+ "RUNNING_WALKING_SENSOR_ON_HIP": 1091,
+ "CYCLING": 1152,
+ "CYCLING_COMPUTER": 1153,
+ "CYCLING_SPEED_SENSOR": 1154,
+ "CYCLING_CADENCE_SENSOR": 1155,
+ "CYCLING_POWER_SENSOR": 1156,
+ "CYCLING_SPEED_AND_CADENCE_SENSOR": 1157,
+ "PULSE_OXIMETER": 3136,
+ "PULSE_OXIMETER_FINGERTIP": 3137,
+ "PULSE_OXIMETER_WRIST": 3138,
+ "WEIGHT_SCALE": 3200,
+ "PERSONAL_MOBILITY": 3264,
+ "PERSONAL_MOBILITY_WHEELCHAIR": 3265,
+ "PERSONAL_MOBILITY_SCOOTER": 3266,
+ "GLUCOSE_MONITOR": 3328,
+ "SPORTS_ACTIVITY": 5184,
+ "SPORTS_ACTIVITY_LOCATION_DISPLAY": 5185,
+ "SPORTS_ACTIVITY_LOCATION_AND_NAV_DISPLAY": 5186,
+ "SPORTS_ACTIVITY_LOCATION_POD": 5187,
+ "SPORTS_ACTIVITY_LOCATION_AND_NAV_POD": 5188,
+}
+
+### End Appearance Constants ###
+
+# Attribute Record values from the Bluetooth Specification
+# Version 5, Vol 3, Part B
+bt_attribute_values = {
+ 'ATTR_SERVICE_RECORD_HANDLE': 0x0000,
+ 'ATTR_SERVICE_CLASS_ID_LIST': 0x0001,
+ 'ATTR_SERVICE_RECORD_STATE': 0x0002,
+ 'ATTR_SERVICE_ID': 0x0003,
+ 'ATTR_PROTOCOL_DESCRIPTOR_LIST': 0x0004,
+ 'ATTR_ADDITIONAL_PROTOCOL_DESCRIPTOR_LIST': 0x000D,
+ 'ATTR_BROWSE_GROUP_LIST': 0x0005,
+ 'ATTR_LANGUAGE_BASE_ATTRIBUTE_ID_LIST': 0x0006,
+ 'ATTR_SERVICE_INFO_TIME_TO_LIVE': 0x0007,
+ 'ATTR_SERVICE_AVAILABILITY': 0x0008,
+ 'ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST': 0x0009,
+ 'ATTR_A2DP_SUPPORTED_FEATURES': 0x0311,
+}
diff --git a/system/blueberry/tests/gd_sl4a/lib/gd_sl4a_base_test.py b/system/blueberry/tests/gd_sl4a/lib/gd_sl4a_base_test.py
new file mode 100644
index 0000000000..a5ae587ff9
--- /dev/null
+++ b/system/blueberry/tests/gd_sl4a/lib/gd_sl4a_base_test.py
@@ -0,0 +1,158 @@
+#!/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.
+
+import traceback
+import os
+import logging
+
+from functools import wraps
+from grpc import RpcError
+
+from mobly import signals
+from mobly.base_test import BaseTestClass
+from mobly.controllers.android_device_lib.adb import AdbError
+from mobly.controllers import android_device
+from mobly.controllers.android_device import MOBLY_CONTROLLER_CONFIG_NAME as ANDROID_DEVICE_COFNIG_NAME
+from mobly.controllers.android_device_lib.jsonrpc_client_base import \
+ AppRestoreConnectionError
+from mobly.controllers.android_device_lib.services.sl4a_service import Sl4aService
+import mobly.controllers.android_device_lib.sl4a_client as sl4a_client
+
+from blueberry.tests.gd.cert.context import get_current_context
+from blueberry.tests.gd.cert.gd_device import MOBLY_CONTROLLER_CONFIG_NAME as GD_DEVICE_CONFIG_NAME
+from blueberry.tests.gd_sl4a.lib.ble_lib import enable_bluetooth, disable_bluetooth, BleLib
+from blueberry.facade import rootservice_pb2 as facade_rootservice
+from blueberry.tests.gd.cert import gd_device
+
+
+class GdSl4aBaseTestClass(BaseTestClass):
+
+ SUBPROCESS_WAIT_TIMEOUT_SECONDS = 10
+
+ def setup_class(self, cert_module):
+ 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[GD_DEVICE_CONFIG_NAME]:
+ config['verbose_mode'] = self.verbose_mode
+ self.cert_module = cert_module
+
+ # Parse and construct GD device objects
+ self.gd_devices = self.register_controller(gd_device, required=True)
+ self.cert = self.gd_devices[0]
+
+ # Parse and construct Android device objects
+ server_port = int(self.controller_configs[ANDROID_DEVICE_COFNIG_NAME][0]['server_port'])
+ forwarded_port = int(self.controller_configs[ANDROID_DEVICE_COFNIG_NAME][0]['forwarded_port'])
+ sl4a_client._DEVICE_SIDE_PORT = server_port
+ sl4a_client._APP_START_WAIT_TIME = 0.5
+ self.android_devices = self.register_controller(android_device, required=True)
+ self.dut = self.android_devices[0]
+ self.dut.services.register('sl4a', Sl4aService, start_service=False)
+ try:
+ self.dut.sl4a.start()
+ except AppRestoreConnectionError:
+ pass
+ try:
+ self.dut.sl4a.clear_host_port()
+ except AdbError:
+ pass
+ sl4a_client._APP_START_WAIT_TIME = 2 * 60
+ self.dut.sl4a.restore_app_connection(port=forwarded_port)
+
+ # Enable full btsnoop log
+ self.dut.adb.shell("setprop persist.bluetooth.btsnooplogmode full")
+ getprop_result = self.dut.adb.shell("getprop persist.bluetooth.btsnooplogmode") == "full"
+ if not getprop_result:
+ self.dut.log.warning("Failed to enable Bluetooth Hci Snoop Logging.")
+
+ self.ble = BleLib(dut=self.dut)
+
+ def teardown_class(self):
+ pass
+
+ def setup_test(self):
+ self.cert.rootservice.StartStack(
+ facade_rootservice.StartStackRequest(
+ module_under_test=facade_rootservice.BluetoothModule.Value(self.cert_module),))
+ self.cert.wait_channel_ready()
+
+ self.timer_list = []
+ self.dut.ed.clear_all_events()
+ self.dut.sl4a.setScreenTimeout(500)
+ self.dut.sl4a.wakeUpNow()
+
+ # Always start tests with Bluetooth enabled and BLE disabled.
+ self.dut.sl4a.bluetoothDisableBLE()
+ disable_bluetooth(self.dut.sl4a, self.dut.ed)
+ # Enable full verbose logging for Bluetooth
+ self.dut.adb.shell("device_config put bluetooth INIT_logging_debug_enabled_for_all true")
+ # Then enable Bluetooth
+ enable_bluetooth(self.dut.sl4a, self.dut.ed)
+ self.dut.sl4a.bluetoothDisableBLE()
+ return True
+
+ def teardown_test(self):
+ # Make sure BLE is disabled and Bluetooth is disabled after test
+ self.dut.sl4a.bluetoothDisableBLE()
+ disable_bluetooth(self.dut.sl4a, self.dut.ed)
+ self.cert.rootservice.StopStack(facade_rootservice.StopStackRequest())
+
+ # TODO: split cert logcat logs into individual tests
+ current_test_dir = get_current_context().get_full_output_path()
+
+ # Pull DUT logs
+ self.pull_dut_logs(current_test_dir)
+
+ # Pull CERT logs
+ self.cert.pull_logs(current_test_dir)
+
+ def pull_dut_logs(self, base_dir):
+ try:
+ self.dut.adb.pull([
+ "/data/misc/bluetooth/logs/btsnoop_hci.log",
+ os.path.join(base_dir, "DUT_%s_btsnoop_hci.log" % self.dut.serial)
+ ])
+ self.dut.adb.pull([
+ "/data/misc/bluedroid/bt_config.conf",
+ os.path.join(base_dir, "DUT_%s_bt_config.conf" % self.dut.serial)
+ ])
+ self.dut.adb.pull([
+ "/data/misc/bluedroid/bt_config.bak",
+ os.path.join(base_dir, "DUT_%s_bt_config.bak" % self.dut.serial)
+ ])
+ except AdbError as error:
+ logging.warning("Failed to pull logs from DUT: " + str(error))
+
+ def __getattribute__(self, name):
+ attr = super().__getattribute__(name)
+ if not callable(attr) or not GdSl4aBaseTestClass.__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" % (exception_info))
+
+ 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 GdSl4aBaseTestClass.__ENTRY_METHODS
diff --git a/system/bta/Android.bp b/system/bta/Android.bp
index 363541be55..03a35f9489 100644
--- a/system/bta/Android.bp
+++ b/system/bta/Android.bp
@@ -99,6 +99,8 @@ cc_library_static {
"le_audio/state_machine.cc",
"le_audio/client_parser.cc",
"le_audio/client_audio.cc",
+ "le_audio/le_audio_set_configuration_provider.cc",
+ "le_audio/le_audio_set_configuration_provider_json.cc",
"le_audio/le_audio_types.cc",
"has/has_client.cc",
"has/has_ctp.cc",
@@ -140,13 +142,13 @@ cc_library_static {
],
static_libs: [
"avrcp-target-service",
+ "libflatbuffers-cpp",
"lib-bt-packets",
"libbt-platform-protos-lite",
],
shared_libs: [
"android.hardware.bluetooth.audio@2.0",
"android.hardware.bluetooth.audio@2.1",
- "android.hardware.bluetooth.audio@2.2",
],
target: {
android: {
@@ -155,6 +157,9 @@ cc_library_static {
],
},
},
+ generated_headers: [
+ "LeAudioSetConfigSchemas_h",
+ ],
host_supported: true,
}
@@ -188,6 +193,12 @@ cc_test {
"libosi",
"libbt-common",
],
+ data: [
+ ":audio_set_scenarios_bfbs",
+ ":audio_set_scenarios_json",
+ ":audio_set_configurations_bfbs",
+ ":audio_set_configurations_json",
+ ],
}
cc_test {
@@ -430,6 +441,78 @@ cc_test {
},
}
+genrule {
+ name: "LeAudioSetConfigSchemas_h",
+ tools: [
+ "flatc",
+ ],
+ cmd: "$(location flatc) -I packages/modules/Bluetooth/system/ -o $(genDir) --cpp $(in) ",
+ srcs: [
+ "le_audio/audio_set_configurations.fbs",
+ "le_audio/audio_set_scenarios.fbs",
+ ],
+ out: [
+ "audio_set_configurations_generated.h",
+ "audio_set_scenarios_generated.h",
+ ],
+}
+
+genrule {
+ name: "LeAudioSetScenariosSchema_bfbs",
+ tools: [
+ "flatc",
+ ],
+ cmd: "$(location flatc) -I packages/modules/Bluetooth/system/ -b --schema -o $(genDir) $(in) ",
+ srcs: [
+ "le_audio/audio_set_scenarios.fbs",
+ ],
+ out: [
+ "audio_set_scenarios.bfbs",
+ ],
+}
+
+genrule {
+ name: "LeAudioSetConfigsSchema_bfbs",
+ tools: [
+ "flatc",
+ ],
+ cmd: "$(location flatc) -I packages/modules/Bluetooth/system/ -b --schema -o $(genDir) $(in) ",
+ srcs: [
+ "le_audio/audio_set_configurations.fbs",
+ ],
+ out: [
+ "audio_set_configurations.bfbs",
+ ],
+}
+
+prebuilt_etc {
+ name: "audio_set_scenarios_bfbs",
+ src: ":LeAudioSetScenariosSchema_bfbs",
+ filename: "audio_set_scenarios.bfbs",
+ sub_dir: "bluetooth/le_audio",
+}
+
+prebuilt_etc {
+ name: "audio_set_scenarios_json",
+ src: "le_audio/audio_set_scenarios.json",
+ filename_from_src: true,
+ sub_dir: "bluetooth/le_audio",
+}
+
+prebuilt_etc {
+ name: "audio_set_configurations_bfbs",
+ src: ":LeAudioSetConfigsSchema_bfbs",
+ filename: "audio_set_configurations.bfbs",
+ sub_dir: "bluetooth/le_audio",
+}
+
+prebuilt_etc {
+ name: "audio_set_configurations_json",
+ src: "le_audio/audio_set_configurations.json",
+ filename_from_src: true,
+ sub_dir: "bluetooth/le_audio",
+}
+
// bta unit tests for LE Audio
// ========================================================
cc_test {
@@ -440,6 +523,19 @@ cc_test {
"clang_coverage_bin",
],
host_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ android: {
+ cflags: [
+ "-DOS_ANDROID",
+ ],
+ sanitize: {
+ misc_undefined: ["bounds"],
+ },
+ },
+ },
include_dirs: [
"packages/modules/Bluetooth/system",
"packages/modules/Bluetooth/system/bta/include",
@@ -460,6 +556,7 @@ cc_test {
"le_audio/client_parser_test.cc",
"le_audio/devices.cc",
"le_audio/devices_test.cc",
+ "le_audio/le_audio_set_configuration_provider_json.cc",
"le_audio/le_audio_types.cc",
"le_audio/le_audio_types_test.cc",
"le_audio/mock_iso_manager.cc",
@@ -468,6 +565,15 @@ cc_test {
"le_audio/state_machine_test.cc",
"le_audio/mock_codec_manager.cc",
],
+ data: [
+ ":audio_set_scenarios_bfbs",
+ ":audio_set_scenarios_json",
+ ":audio_set_configurations_bfbs",
+ ":audio_set_configurations_json"
+ ],
+ generated_headers: [
+ "LeAudioSetConfigSchemas_h",
+ ],
shared_libs: [
"libprotobuf-cpp-lite",
"libcrypto",
@@ -477,6 +583,7 @@ cc_test {
"libgmock",
"libbt-common",
"libbt-protos-lite",
+ "libflatbuffers-cpp",
"libosi",
],
sanitize: {
@@ -507,6 +614,7 @@ cc_test {
"le_audio/client_parser.cc",
"le_audio/devices.cc",
"le_audio/le_audio_client_test.cc",
+ "le_audio/le_audio_set_configuration_provider_json.cc",
"le_audio/le_audio_types.cc",
"le_audio/mock_iso_manager.cc",
"le_audio/mock_le_audio_client_audio.cc",
@@ -523,7 +631,6 @@ cc_test {
shared_libs: [
"android.hardware.bluetooth.audio@2.0",
"android.hardware.bluetooth.audio@2.1",
- "android.hardware.bluetooth.audio@2.2",
"libprotobuf-cpp-lite",
"libcrypto",
"liblog",
@@ -533,10 +640,19 @@ cc_test {
"libgmock",
"libbt-common",
"libbt-protos-lite",
+ "libflatbuffers-cpp",
"libosi",
- "liblc3codec",
"liblc3",
],
+ data: [
+ ":audio_set_scenarios_bfbs",
+ ":audio_set_scenarios_json",
+ ":audio_set_configurations_bfbs",
+ ":audio_set_configurations_json",
+ ],
+ generated_headers: [
+ "LeAudioSetConfigSchemas_h",
+ ],
target: {
android: {
shared_libs: [
@@ -580,6 +696,7 @@ cc_test {
"le_audio/broadcaster/state_machine_test.cc",
"le_audio/le_audio_types.cc",
"le_audio/mock_iso_manager.cc",
+ "le_audio/mock_codec_manager.cc",
],
shared_libs: [
"libprotobuf-cpp-lite",
@@ -631,6 +748,7 @@ cc_test {
"le_audio/mock_iso_manager.cc",
"le_audio/mock_le_audio_client_audio.cc",
"test/common/mock_controller.cc",
+ "le_audio/mock_codec_manager.cc",
],
shared_libs: [
"libprotobuf-cpp-lite",
diff --git a/system/bta/ag/bta_ag_act.cc b/system/bta/ag/bta_ag_act.cc
index adf08beafc..1ba68bcc44 100644
--- a/system/bta/ag/bta_ag_act.cc
+++ b/system/bta/ag/bta_ag_act.cc
@@ -373,7 +373,6 @@ void bta_ag_rfc_close(tBTA_AG_SCB* p_scb,
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);
diff --git a/system/bta/csis/csis_client_test.cc b/system/bta/csis/csis_client_test.cc
index f3aaefe098..1ad837f637 100644
--- a/system/bta/csis/csis_client_test.cc
+++ b/system/bta/csis/csis_client_test.cc
@@ -75,12 +75,12 @@ RawAddress GetTestAddress(int index) {
class MockCsisLockCallback {
public:
MockCsisLockCallback() = default;
+ MockCsisLockCallback(const MockCsisLockCallback&) = delete;
+ MockCsisLockCallback& operator=(const MockCsisLockCallback&) = delete;
+
~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;
@@ -93,6 +93,9 @@ void SetMockCsisLockCallback(MockCsisLockCallback* mock) {
class MockCsisCallbacks : public CsisClientCallbacks {
public:
MockCsisCallbacks() = default;
+ MockCsisCallbacks(const MockCsisCallbacks&) = delete;
+ MockCsisCallbacks& operator=(const MockCsisCallbacks&) = delete;
+
~MockCsisCallbacks() override = default;
MOCK_METHOD((void), OnConnectionState,
@@ -110,9 +113,6 @@ class MockCsisCallbacks : public CsisClientCallbacks {
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 {
diff --git a/system/bta/dm/bta_dm_act.cc b/system/bta/dm/bta_dm_act.cc
index 2ecc3e906a..1ab4ca5592 100644
--- a/system/bta/dm/bta_dm_act.cc
+++ b/system/bta/dm/bta_dm_act.cc
@@ -264,8 +264,6 @@ void bta_dm_enable(tBTA_DM_SEC_CBACK* p_sec_cback) {
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();
}
@@ -328,9 +326,6 @@ void BTA_dm_on_hw_off() {
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() {
@@ -345,7 +340,6 @@ void BTA_dm_on_hw_on() {
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);
@@ -495,21 +489,19 @@ static void bta_dm_wait_for_acl_to_drain_cback(void* data) {
const WaitForAllAclConnectionsToDrain* pass =
WaitForAllAclConnectionsToDrain::FromAlarmCallbackData(data);
- if (BTM_GetNumAclLinks() &&
+ if (BTM_GetNumAclLinks() && force_disconnect_all_acl_connections() &&
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());
- }
+ 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
+ // No ACL links to close were up or is second pass at ACL closure
LOG_INFO("Ensuring all ACL connections have been properly flushed");
bluetooth::shim::ACL_Shutdown();
@@ -3998,6 +3990,20 @@ void bta_dm_proc_open_evt(tBTA_GATTC_OPEN* p_data) {
/*******************************************************************************
*
+ * Function bta_dm_proc_open_evt
+ *
+ * Description process BTA_GATTC_OPEN_EVT in DM.
+ *
+ * Parameters:
+ *
+ ******************************************************************************/
+void bta_dm_clear_event_filter(void) {
+ VLOG(1) << "bta_dm_clear_event_filter in bta_dm_act";
+ bluetooth::shim::BTM_ClearEventFilter();
+}
+
+/*******************************************************************************
+ *
* Function bta_dm_gattc_callback
*
* Description This is GATT client callback function used in DM.
diff --git a/system/bta/dm/bta_dm_api.cc b/system/bta/dm/bta_dm_api.cc
index c9e5166353..5e1a8787f7 100644
--- a/system/bta/dm/bta_dm_api.cc
+++ b/system/bta/dm/bta_dm_api.cc
@@ -670,3 +670,17 @@ void BTA_DmBleCsisObserve(bool observe, tBTA_DM_SEARCH_CBACK* p_results_cb) {
*
******************************************************************************/
void BTA_VendorInit(void) { APPL_TRACE_API("BTA_VendorInit"); }
+
+/*******************************************************************************
+ *
+ * Function BTA_DmClearEventFilter
+ *
+ * Description This function clears the event filter
+ *
+ * Returns void
+ *
+ ******************************************************************************/
+void BTA_DmClearEventFilter(void) {
+ APPL_TRACE_API("BTA_DmClearEventFilter");
+ do_in_main_thread(FROM_HERE, base::Bind(bta_dm_clear_event_filter));
+}
diff --git a/system/bta/dm/bta_dm_int.h b/system/bta/dm/bta_dm_int.h
index 02d25eb12b..637c22aef9 100644
--- a/system/bta/dm/bta_dm_int.h
+++ b/system/bta/dm/bta_dm_int.h
@@ -310,22 +310,14 @@ extern tBTA_DM_CONNECTED_SRVCS bta_dm_conn_srvcs;
/* 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;
@@ -349,7 +341,6 @@ typedef struct {
tBTA_DM_ENCRYPT_CBACK* p_encrypt_cback;
alarm_t* switch_delay_timer;
-
} tBTA_DM_CB;
/* DM search control block */
@@ -553,6 +544,8 @@ 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);
+extern void bta_dm_clear_event_filter(void);
+
uint8_t bta_dm_search_get_state();
void bta_dm_search_set_state(uint8_t state);
diff --git a/system/bta/gatt/database.cc b/system/bta/gatt/database.cc
index 433fd55ac0..184ff9223f 100644
--- a/system/bta/gatt/database.cc
+++ b/system/bta/gatt/database.cc
@@ -20,6 +20,7 @@
#include <base/logging.h>
+#include <algorithm>
#include <list>
#include <memory>
#include <sstream>
diff --git a/system/bta/groups/groups_test.cc b/system/bta/groups/groups_test.cc
index 8966284df5..2299c573e3 100644
--- a/system/bta/groups/groups_test.cc
+++ b/system/bta/groups/groups_test.cc
@@ -52,6 +52,9 @@ RawAddress GetTestAddress(int index) {
class MockGroupsCallbacks : public DeviceGroupsCallbacks {
public:
MockGroupsCallbacks() = default;
+ MockGroupsCallbacks(const MockGroupsCallbacks&) = delete;
+ MockGroupsCallbacks& operator=(const MockGroupsCallbacks&) = delete;
+
~MockGroupsCallbacks() override = default;
MOCK_METHOD((void), OnGroupAdded,
@@ -69,9 +72,6 @@ class MockGroupsCallbacks : public DeviceGroupsCallbacks {
(const RawAddress& address, const bluetooth::Uuid& uuid,
int group_id),
(override));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockGroupsCallbacks);
};
class GroupsTest : public ::testing::Test {
diff --git a/system/bta/has/has_client.cc b/system/bta/has/has_client.cc
index 7c6bbdc3c9..044713437f 100644
--- a/system/bta/has/has_client.cc
+++ b/system/bta/has/has_client.cc
@@ -1044,14 +1044,14 @@ class HasClientImpl : public HasClient {
/* Journal update */
device->has_journal_.Append(HasJournalRecord(features, true));
- /* When service is not yet validated, report the available device and
- * notify features otherwise.
+ /* When service is not yet validated, report the available device with
+ * features.
*/
- if (!device->isGattServiceValid()) {
+ if (!device->isGattServiceValid())
callbacks_->OnDeviceAvailable(device->addr, device->GetFeatures());
- } else {
- callbacks_->OnFeaturesUpdate(device->addr, device->GetFeatures());
- }
+
+ /* Notify features */
+ callbacks_->OnFeaturesUpdate(device->addr, device->GetFeatures());
MarkDeviceValidIfInInitialDiscovery(*device);
}
diff --git a/system/bta/has/has_client_test.cc b/system/bta/has/has_client_test.cc
index c46e034de7..571686981c 100644
--- a/system/bta/has/has_client_test.cc
+++ b/system/bta/has/has_client_test.cc
@@ -104,6 +104,9 @@ static uint16_t GetTestConnId(const RawAddress& address) {
class MockHasCallbacks : public HasClientCallbacks {
public:
MockHasCallbacks() = default;
+ MockHasCallbacks(const MockHasCallbacks&) = delete;
+ MockHasCallbacks& operator=(const MockHasCallbacks&) = delete;
+
~MockHasCallbacks() override = default;
MOCK_METHOD((void), OnConnectionState,
@@ -133,9 +136,6 @@ class MockHasCallbacks : public HasClientCallbacks {
((std::variant<RawAddress, int> addr_or_group_id),
uint8_t preset_index, ErrorCode error_code),
(override));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockHasCallbacks);
};
class HasClientTestBase : public ::testing::Test {
diff --git a/system/bta/has/has_types.h b/system/bta/has/has_types.h
index 89ed82a8ce..d726f07cf7 100644
--- a/system/bta/has/has_types.h
+++ b/system/bta/has/has_types.h
@@ -72,7 +72,7 @@ static_assert(sizeof(HasGattOpContext) <= sizeof(void*));
/* Service UUIDs */
/* FIXME: actually these were not yet assigned - using placeholders for now. */
static const bluetooth::Uuid kUuidHearingAccessService =
- bluetooth::Uuid::From16Bit(0xEEEE);
+ bluetooth::Uuid::From16Bit(0x1854);
static const bluetooth::Uuid kUuidHearingAidFeatures =
bluetooth::Uuid::From16Bit(0xEEED);
static const bluetooth::Uuid kUuidHearingAidPresetControlPoint =
diff --git a/system/bta/hearing_aid/hearing_aid.cc b/system/bta/hearing_aid/hearing_aid.cc
index b8667fef0a..3aef56e9e1 100644
--- a/system/bta/hearing_aid/hearing_aid.cc
+++ b/system/bta/hearing_aid/hearing_aid.cc
@@ -41,7 +41,6 @@
#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"
@@ -589,9 +588,9 @@ class HearingAidImpl : public HearingAid {
hearingDevice->first_connection = true;
hearingDevice->service_changed_rcvd = true;
BtaGattQueue::Clean(hearingDevice->conn_id);
- if (hearingDevice->gap_handle) {
+ if (hearingDevice->gap_handle != GAP_INVALID_HANDLE) {
GAP_ConnClose(hearingDevice->gap_handle);
- hearingDevice->gap_handle = 0;
+ hearingDevice->gap_handle = GAP_INVALID_HANDLE;
}
}
@@ -1332,9 +1331,20 @@ class HearingAidImpl : public HearingAid {
case GAP_EVT_CONN_CLOSED:
LOG(INFO) << __func__
<< ": GAP_EVT_CONN_CLOSED: " << hearingDevice->address
- << ", playback_started=" << hearingDevice->playback_started;
- /* Disconnect profile when data channel is not available */
- Disconnect(hearingDevice->address);
+ << ", playback_started=" << hearingDevice->playback_started
+ << ", connecting_actively="
+ << hearingDevice->connecting_actively;
+ if (hearingDevice->connecting_actively) {
+ /* Disconnect connection when data channel is not available */
+ BTA_GATTC_Close(hearingDevice->conn_id);
+ } else {
+ /* Just clean data channel related parameter when data channel is
+ * available */
+ hearingDevice->gap_handle = GAP_INVALID_HANDLE;
+ hearingDevice->accepting_audio = false;
+ hearingDevice->playback_started = false;
+ hearingDevice->command_acked = false;
+ }
break;
case GAP_EVT_CONN_DATA_AVAIL: {
DVLOG(2) << "GAP_EVT_CONN_DATA_AVAIL";
@@ -1461,7 +1471,7 @@ class HearingAidImpl : public HearingAid {
bool connected = hearingDevice->accepting_audio;
bool connecting_by_user = hearingDevice->connecting_actively;
- LOG(INFO) << "GAP_EVT_CONN_CLOSED: " << hearingDevice->address
+ LOG(INFO) << __func__ << ": " << hearingDevice->address
<< ", playback_started=" << hearingDevice->playback_started
<< ", accepting_audio=" << hearingDevice->accepting_audio;
@@ -1480,17 +1490,19 @@ class HearingAidImpl : public HearingAid {
DoDisconnectCleanUp(hearingDevice);
- hearingDevices.Remove(address);
-
if (!connected) {
/* In case user wanted to connect, sent DISCONNECTED state */
- if (connecting_by_user)
+ if (connecting_by_user) {
callbacks->OnConnectionState(ConnectionState::DISCONNECTED, address);
-
+ }
+ /* Do remove device when the address is useless. */
+ hearingDevices.Remove(address);
return;
}
callbacks->OnConnectionState(ConnectionState::DISCONNECTED, address);
+ /* Do remove device when the address is useless. */
+ hearingDevices.Remove(address);
for (const auto& device : hearingDevices.devices) {
if (device.accepting_audio) return;
}
@@ -1549,9 +1561,9 @@ class HearingAidImpl : public HearingAid {
hearingDevice->conn_id = 0;
}
- if (hearingDevice->gap_handle) {
+ if (hearingDevice->gap_handle != GAP_INVALID_HANDLE) {
GAP_ConnClose(hearingDevice->gap_handle);
- hearingDevice->gap_handle = 0;
+ hearingDevice->gap_handle = GAP_INVALID_HANDLE;
}
hearingDevice->accepting_audio = false;
diff --git a/system/bta/include/bta_api.h b/system/bta/include/bta_api.h
index 701de0aee8..3c0bd4b38a 100644
--- a/system/bta/include/bta_api.h
+++ b/system/bta/include/bta_api.h
@@ -1194,4 +1194,15 @@ extern void BTA_DmBleGetEnergyInfo(tBTA_BLE_ENERGY_INFO_CBACK* p_cmpl_cback);
******************************************************************************/
extern void BTA_VendorInit(void);
+/*******************************************************************************
+ *
+ * Function BTA_DmClearEventFilter
+ *
+ * Description This function clears the event filter
+ *
+ * Returns void
+ *
+ ******************************************************************************/
+extern void BTA_DmClearEventFilter(void);
+
#endif /* BTA_API_H */
diff --git a/system/bta/include/bta_hearing_aid_api.h b/system/bta/include/bta_hearing_aid_api.h
index b7ac365335..3ae46fd751 100644
--- a/system/bta/include/bta_hearing_aid_api.h
+++ b/system/bta/include/bta_hearing_aid_api.h
@@ -26,6 +26,7 @@
#include <functional>
#include <vector>
+#include "stack/include/gap_api.h"
#include "types/raw_address.h"
constexpr uint16_t HEARINGAID_MAX_NUM_UUIDS = 1;
@@ -166,7 +167,7 @@ struct HearingDevice {
connection_update_status(NONE),
accepting_audio(false),
conn_id(0),
- gap_handle(0),
+ gap_handle(GAP_INVALID_HANDLE),
audio_control_point_handle(audio_control_point_handle),
audio_status_handle(audio_status_handle),
audio_status_ccc_handle(audio_status_ccc_handle),
@@ -190,7 +191,7 @@ struct HearingDevice {
connection_update_status(NONE),
accepting_audio(false),
conn_id(0),
- gap_handle(0),
+ gap_handle(GAP_INVALID_HANDLE),
audio_status_handle(0),
audio_status_ccc_handle(0),
service_changed_ccc_handle(0),
diff --git a/system/bta/include/bta_le_audio_api.h b/system/bta/include/bta_le_audio_api.h
index ba878ebfc7..832910bcd5 100644
--- a/system/bta/include/bta_le_audio_api.h
+++ b/system/bta/include/bta_le_audio_api.h
@@ -28,6 +28,7 @@ class LeAudioHalVerifier {
public:
static bool SupportsLeAudio();
static bool SupportsLeAudioHardwareOffload();
+ static bool SupportsLeAudioBroadcast();
};
/* Interface class */
@@ -35,10 +36,12 @@ class LeAudioClient {
public:
virtual ~LeAudioClient(void) = default;
- static void Initialize(bluetooth::le_audio::LeAudioClientCallbacks* callbacks,
- base::Closure initCb,
- base::Callback<bool()> hal_2_1_verifier);
- static void Cleanup(void);
+ static void Initialize(
+ bluetooth::le_audio::LeAudioClientCallbacks* callbacks,
+ base::Closure initCb, base::Callback<bool()> hal_2_1_verifier,
+ const std::vector<bluetooth::le_audio::btle_audio_codec_config_t>&
+ offloading_preference);
+ static void Cleanup(base::Callback<void()> cleanupCb);
static LeAudioClient* Get(void);
static void DebugDump(int fd);
@@ -55,4 +58,7 @@ class LeAudioClient {
virtual std::vector<RawAddress> GetGroupDevices(const int group_id) = 0;
static void AddFromStorage(const RawAddress& addr, bool autoconnect);
static bool IsLeAudioClientRunning();
+
+ static void InitializeAudioSetConfigurationProvider(void);
+ static void CleanupAudioSetConfigurationProvider(void);
};
diff --git a/system/bta/le_audio/audio_set_configurations.fbs b/system/bta/le_audio/audio_set_configurations.fbs
new file mode 100644
index 0000000000..392263ad0c
--- /dev/null
+++ b/system/bta/le_audio/audio_set_configurations.fbs
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2022 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.
+ *
+ */
+namespace bluetooth.le_audio;
+enum CodecSpecificLtvGenericTypes : byte {
+ SUPPORTED_SAMPLING_FREQUENCY = 0x01,
+ SUPPORTED_FRAME_DURATION = 0x02,
+ SUPPORTED_AUDIO_CHANNEL_ALLOCATION = 0x03,
+ SUPPORTED_OCTETS_PER_CODEC_FRAME = 0x04,
+ SUPPORTED_CODEC_FRAME_BLOCKS_PER_SDU = 0x05,
+}
+/// Note: Holds either a single value (when `value_width == 0`) or multiple
+/// values if `value.length()` is no-remainder divisible by the non-zero
+/// `value_width`.
+/// Note: Consider extending it with `flags` field, to hold additional info like
+/// IsBitfield, IsRange, etc. if we need these type-specific validations.
+table CompoundValue {
+ value: [ubyte] (required);
+ value_width: ubyte = 0;
+}
+table CodecSpecificConfiguration {
+ name: string;
+ type: ubyte (key);
+ compound_value: CompoundValue;
+}
+struct CodecId {
+ coding_format: ubyte;
+ vendor_company_id : ushort;
+ vendor_codec_id : ushort;
+}
+enum AudioSetConfigurationStrategy : byte {
+ MONO_ONE_CIS_PER_DEVICE = 0x00,
+ STEREO_TWO_CISES_PER_DEVICE = 0x01,
+ STEREO_ONE_CIS_PER_DEVICE = 0x02,
+}
+enum AudioSetConfigurationDirection : byte {
+ SINK = 0x01,
+ SOURCE = 0x02,
+}
+table AudioSetSubConfiguration {
+ device_cnt: ubyte;
+ ase_cnt: ubyte;
+ direction: AudioSetConfigurationDirection = SINK;
+ configuration_strategy: AudioSetConfigurationStrategy;
+ codec_id : CodecId (required);
+ codec_configuration: [CodecSpecificConfiguration] (required);
+}
+/// Each set configration can contain multiple logical subconfigurations, which
+/// all must be configurable with the current set of audio devices. For example,
+/// one can define multiple output stream configurations with different
+/// qualities, or assign different configurations to each stream direction.
+table AudioSetConfiguration {
+ name: string (key, required);
+ subconfigurations: [AudioSetSubConfiguration] (required);
+}
+table AudioSetConfigurations {
+ _comments_: [string];
+ configurations: [AudioSetConfiguration] (required);
+}
+root_type AudioSetConfigurations;
diff --git a/system/bta/le_audio/audio_set_configurations.json b/system/bta/le_audio/audio_set_configurations.json
new file mode 100644
index 0000000000..08453307a1
--- /dev/null
+++ b/system/bta/le_audio/audio_set_configurations.json
@@ -0,0 +1,2118 @@
+{
+ "_comments_": [
+ " == Audio Set Configurations == ",
+ " Example values which can be used as 'codec_configuration.type'",
+ " Codec Configuration parameter types:",
+ " SUPPORTED_SAMPLING_FREQUENCY = 1",
+ " SUPPORTED_FRAME_DURATION = 2",
+ " SUPPORTED_AUDIO_CHANNEL_ALLOCATION = 3",
+ " SUPPORTED_OCTETS_PER_CODEC_FRAME = 4",
+ " SUPPORTED_CODEC_FRAME_BLOCKS_PER_SDU = 5",
+ " Example values which can be used as 'codec_configuration.compound_value'",
+ " Codec Coding formats:",
+ " LC3 = 6",
+ " ASE Configuration strategies:",
+ " MONO_ONE_CIS_PER_DEVICE = 0",
+ " STEREO_TWO_CISES_PER_DEVICE = 1",
+ " STEREO_ONE_CIS_PER_DEVICE = 2",
+ " Sampling Frequencies: ",
+ " 8000Hz = 1",
+ " 11025Hz = 2",
+ " 16000Hz = 3",
+ " 22050Hz = 4",
+ " 24000Hz = 5",
+ " 32000Hz = 6",
+ " 44100Hz = 7",
+ " 48000Hz = 8",
+ " 88200Hz = 9",
+ " 96000Hz = 10",
+ " 176400Hz = 11",
+ " 192000Hz = 12",
+ " 384000Hz = 13",
+ " Frame Durations:",
+ " 7500us = 0",
+ " 10000us = 1"
+ ],
+ "configurations": [
+ {
+ "name": "DualDev_OneChanStereoSnk_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 4,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 4,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_4",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_4",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/system/bta/le_audio/audio_set_scenarios.fbs b/system/bta/le_audio/audio_set_scenarios.fbs
new file mode 100644
index 0000000000..301a5c1bb7
--- /dev/null
+++ b/system/bta/le_audio/audio_set_scenarios.fbs
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2022 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.
+ *
+ */
+namespace bluetooth.le_audio;
+/// Scenario represents the use case such as "Media", "Conversation", etc.
+/// Each scenario can list any number of codec configurations by their names in
+/// the order of preference. That means if the first entry does not meet all
+/// the current requirements (such as peer device capabilities etc.) next
+/// configurations are being checked.
+///
+/// The referenced codec configurations are defined by the
+/// audio_set_configurations.fbs schema and loaded from a different source file.
+/// Multiple scenarios can reference same codec configurations.
+table AudioSetScenario {
+ _comments_: [string];
+ name: string (key, required);
+ configurations: [string] (required);
+}
+table AudioSetScenarios {
+ _comments_: [string];
+ scenarios: [AudioSetScenario] (required);
+}
+root_type AudioSetScenarios;
diff --git a/system/bta/le_audio/audio_set_scenarios.json b/system/bta/le_audio/audio_set_scenarios.json
new file mode 100644
index 0000000000..d9f7b8fc7a
--- /dev/null
+++ b/system/bta/le_audio/audio_set_scenarios.json
@@ -0,0 +1,63 @@
+{
+ "_comments_": [
+ "== Audio Set Scenarios ==",
+ " Each defined scenario references externally defined audio set",
+ " configurations, listed in the order of priority."
+ ],
+ "scenarios": [
+ {
+ "name": "Ringtone",
+ "configurations": [
+ "DualDev_OneChanStereoSnk_16_2",
+ "DualDev_OneChanStereoSnk_16_1",
+ "SingleDev_OneChanStereoSnk_16_2",
+ "SingleDev_OneChanStereoSnk_16_1",
+ "SingleDev_TwoChanStereoSnk_16_2",
+ "SingleDev_TwoChanStereoSnk_16_1",
+ "SingleDev_OneChanMonoSnk_16_2",
+ "SingleDev_OneChanMonoSnk_16_1"
+ ]
+ },
+ {
+ "name": "Conversational",
+ "configurations": [
+ "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
+ "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
+ "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2",
+ "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1"
+ ]
+ },
+ {
+ "name": "Media",
+ "configurations": [
+ "DualDev_OneChanStereoSnk_48_4",
+ "DualDev_OneChanStereoSnk_16_2",
+ "DualDev_OneChanStereoSnk_16_1",
+ "SingleDev_OneChanStereoSnk_48_4",
+ "SingleDev_OneChanStereoSnk_16_2",
+ "SingleDev_OneChanStereoSnk_16_1",
+ "SingleDev_TwoChanStereoSnk_48_4",
+ "SingleDev_TwoChanStereoSnk_16_2",
+ "SingleDev_TwoChanStereoSnk_16_1",
+ "SingleDev_OneChanMonoSnk_48_4",
+ "SingleDev_OneChanMonoSnk_16_2",
+ "SingleDev_OneChanMonoSnk_16_1"
+ ]
+ },
+ {
+ "name": "Default",
+ "configurations": [
+ "DualDev_OneChanStereoSnk_16_2",
+ "SingleDev_OneChanStereoSnk_16_2",
+ "SingleDev_TwoChanStereoSnk_16_2",
+ "SingleDev_OneChanMonoSnk_16_2"
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/system/bta/le_audio/broadcaster/broadcaster.cc b/system/bta/le_audio/broadcaster/broadcaster.cc
index 2122fb3585..2744fe9fc9 100644
--- a/system/bta/le_audio/broadcaster/broadcaster.cc
+++ b/system/bta/le_audio/broadcaster/broadcaster.cc
@@ -134,7 +134,7 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
.vendor_codec_id = codec_id.vendor_codec_id,
.codec_specific_params = std::move(codec_spec_data),
},
- .metadata = metadata,
+ .metadata = std::move(metadata),
.bis_configs = {},
}};
@@ -542,7 +542,7 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
encoders_mem_.emplace_back(malloc(encoder_bytes), &std::free);
encoders_.emplace_back(
- lc3_setup_encoder(dt_us, sr_hz, encoders_mem_.back().get()));
+ lc3_setup_encoder(dt_us, sr_hz, 0, encoders_mem_.back().get()));
}
}
diff --git a/system/bta/le_audio/broadcaster/mock_ble_advertising_manager.h b/system/bta/le_audio/broadcaster/mock_ble_advertising_manager.h
index ee1d8749a5..eca09c87ba 100644
--- a/system/bta/le_audio/broadcaster/mock_ble_advertising_manager.h
+++ b/system/bta/le_audio/broadcaster/mock_ble_advertising_manager.h
@@ -27,6 +27,10 @@
class MockBleAdvertisingManager : public BleAdvertisingManager {
public:
MockBleAdvertisingManager() = default;
+ MockBleAdvertisingManager(const MockBleAdvertisingManager&) = delete;
+ MockBleAdvertisingManager& operator=(const MockBleAdvertisingManager&) =
+ delete;
+
~MockBleAdvertisingManager() override = default;
/* Allows getting and setting BleAdvertiserHciInterface dependency */
@@ -99,7 +103,6 @@ class MockBleAdvertisingManager : public BleAdvertisingManager {
(override));
private:
- DISALLOW_COPY_AND_ASSIGN(MockBleAdvertisingManager);
base::WeakPtrFactory<MockBleAdvertisingManager> weak_factory_{this};
BleAdvertiserHciInterface* ble_adv_hci_interface_;
};
diff --git a/system/bta/le_audio/broadcaster/state_machine_test.cc b/system/bta/le_audio/broadcaster/state_machine_test.cc
index d0fc071c13..a203bcab2b 100644
--- a/system/bta/le_audio/broadcaster/state_machine_test.cc
+++ b/system/bta/le_audio/broadcaster/state_machine_test.cc
@@ -53,6 +53,11 @@ class MockBroadcastStatMachineCallbacks
: public IBroadcastStateMachineCallbacks {
public:
MockBroadcastStatMachineCallbacks() = default;
+ MockBroadcastStatMachineCallbacks(const MockBroadcastStatMachineCallbacks&) =
+ delete;
+ MockBroadcastStatMachineCallbacks& operator=(
+ const MockBroadcastStatMachineCallbacks&) = delete;
+
~MockBroadcastStatMachineCallbacks() override = default;
MOCK_METHOD((void), OnStateMachineCreateStatus,
@@ -70,9 +75,6 @@ class MockBroadcastStatMachineCallbacks
MOCK_METHOD((uint32_t), GetSduItv, (uint8_t instance_id), (override));
MOCK_METHOD((uint16_t), GetMaxTransportLatency, (uint8_t instance_id),
(override));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockBroadcastStatMachineCallbacks);
};
class StateMachineTest : public Test {
diff --git a/system/bta/le_audio/client.cc b/system/bta/le_audio/client.cc
index 3aa605e581..71ba18b345 100644
--- a/system/bta/le_audio/client.cc
+++ b/system/bta/le_audio/client.cc
@@ -34,7 +34,6 @@
#include "common/time_util.h"
#include "device/include/controller.h"
#include "devices.h"
-#include "embdrv/lc3_dec/Api/Lc3Decoder.hpp"
#include "embdrv/lc3/include/lc3.h"
#include "gatt/bta_gattc_int.h"
#include "le_audio_types.h"
@@ -175,6 +174,7 @@ class LeAudioClientImpl : public LeAudioClient {
current_sink_codec_config({0, 0, 0, 0}),
lc3_encoder_left_mem(nullptr),
lc3_encoder_right_mem(nullptr),
+ lc3_decoder_mem(nullptr),
lc3_decoder(nullptr),
audio_source_instance_(nullptr),
audio_sink_instance_(nullptr),
@@ -671,9 +671,13 @@ class LeAudioClientImpl : public LeAudioClient {
}
if (active_group_id_ != bluetooth::groups::kGroupUnknown) {
- LOG(WARNING) << __func__ << ", Another group already active: "
- << static_cast<int>(active_group_id_);
- return;
+ if (active_group_id_ == group_id) {
+ LOG(INFO) << __func__ << ", Group is already active: "
+ << static_cast<int>(active_group_id_);
+ callbacks_->OnGroupStatus(active_group_id_, GroupStatus::ACTIVE);
+ return;
+ }
+ LOG(INFO) << __func__ << ", switching active group to: " << group_id;
}
if (!audio_source_instance_) {
@@ -701,21 +705,25 @@ class LeAudioClientImpl : public LeAudioClient {
if (current_source_codec_config.IsInvalid() &&
current_sink_codec_config.IsInvalid()) {
LOG(WARNING) << __func__ << ", unsupported device configurations";
- callbacks_->OnGroupStatus(active_group_id_, GroupStatus::INACTIVE);
return;
}
- /* Expose audio sessions */
- audio_framework_source_config.data_interval_us =
- current_source_codec_config.data_interval_us;
- LeAudioClientAudioSource::Start(audio_framework_source_config,
- audioSinkReceiver);
+ if (active_group_id_ == bluetooth::groups::kGroupUnknown) {
+ /* Expose audio sessions if there was no previous active group */
+ audio_framework_source_config.data_interval_us =
+ current_source_codec_config.data_interval_us;
+ LeAudioClientAudioSource::Start(audio_framework_source_config,
+ audioSinkReceiver);
- audio_framework_sink_config.data_interval_us =
+ audio_framework_sink_config.data_interval_us =
current_source_codec_config.data_interval_us;
- LeAudioClientAudioSink::Start(audio_framework_sink_config,
- audioSourceReceiver);
+ LeAudioClientAudioSink::Start(audio_framework_sink_config,
+ audioSourceReceiver);
+ } else {
+ /* In case there was an active group. Stop the stream */
+ GroupStop(active_group_id_);
+ }
active_group_id_ = group_id;
callbacks_->OnGroupStatus(active_group_id_, GroupStatus::ACTIVE);
@@ -1258,6 +1266,11 @@ class LeAudioClientImpl : public LeAudioClient {
group_remove_node(group, address, true);
}
leAudioDevices_.Remove(address);
+ return;
+ }
+ /* Attempt background re-connect if disconnect was not intended locally */
+ if (reason != GATT_CONN_TERMINATE_LOCAL_HOST) {
+ BTA_GATTC_Open(gatt_if_, address, false, false);
}
}
@@ -1815,8 +1828,8 @@ class LeAudioClientImpl : public LeAudioClient {
uint16_t num_of_frames_per_ch;
int dt_us = current_source_codec_config.data_interval_us;
- int sr_hz = current_source_codec_config.sample_rate;
- num_of_frames_per_ch = lc3_frame_samples(dt_us, sr_hz);
+ int af_hz = audio_framework_source_config.sample_rate;
+ num_of_frames_per_ch = lc3_frame_samples(dt_us, af_hz);
chan_mono.reserve(num_of_frames_per_ch);
for (int i = 0; i < pitch * num_of_frames_per_ch; i += pitch) {
@@ -1842,8 +1855,8 @@ class LeAudioClientImpl : public LeAudioClient {
uint16_t number_of_required_samples_per_channel;
int dt_us = current_source_codec_config.data_interval_us;
- int sr_hz = current_source_codec_config.sample_rate;
- number_of_required_samples_per_channel = lc3_frame_samples(dt_us, sr_hz);
+ int af_hz = audio_framework_source_config.sample_rate;
+ number_of_required_samples_per_channel = lc3_frame_samples(dt_us, af_hz);
for (auto [cis_handle, audio_location] : stream_conf->sink_streams) {
if (audio_location & le_audio::codec_spec_conf::kLeAudioLocationAnyLeft)
@@ -1865,22 +1878,16 @@ class LeAudioClientImpl : public LeAudioClient {
bool mono = (left_cis_handle == 0) || (right_cis_handle == 0);
- int af_hz = audio_framework_source_config.sample_rate;
- LOG_ASSERT(af_hz >= sr_hz) << __func__ << " sample freq issue";
-
- int pitch = af_hz / sr_hz;
-
- LOG(INFO) << __func__ << " pitch " << pitch
- << " data size: " << (int)data.size()
+ LOG(INFO) << __func__ << " data size: " << (int)data.size()
<< " byte count: " << byte_count << " mono: " << mono;
if (!mono) {
- lc3_encode(lc3_encoder_left, (const int16_t*)data.data(), 2 * pitch,
+ lc3_encode(lc3_encoder_left, (const int16_t*)data.data(), 2,
chan_left_enc.size(), chan_left_enc.data());
- lc3_encode(lc3_encoder_right, ((const int16_t*)data.data()) + 1,
- 2 * pitch, chan_right_enc.size(), chan_right_enc.data());
+ lc3_encode(lc3_encoder_right, ((const int16_t*)data.data()) + 1, 2,
+ chan_right_enc.size(), chan_right_enc.data());
} else {
std::vector<int16_t> chan_mono;
- get_mono_stream(data, chan_mono, pitch);
+ get_mono_stream(data, chan_mono);
if (left_cis_handle) {
lc3_encode(lc3_encoder_left, (const int16_t*)chan_mono.data(), 1,
@@ -1914,8 +1921,8 @@ class LeAudioClientImpl : public LeAudioClient {
uint16_t number_of_required_samples_per_channel;
int dt_us = current_source_codec_config.data_interval_us;
- int sr_hz = current_source_codec_config.sample_rate;
- number_of_required_samples_per_channel = lc3_frame_samples(dt_us, sr_hz);
+ int af_hz = audio_framework_source_config.sample_rate;
+ number_of_required_samples_per_channel = lc3_frame_samples(dt_us, af_hz);
if ((int)data.size() < (2 /* bytes per sample */ * num_channels *
number_of_required_samples_per_channel)) {
@@ -1924,24 +1931,22 @@ class LeAudioClientImpl : public LeAudioClient {
}
std::vector<uint8_t> chan_encoded(num_channels * byte_count, 0);
- int af_hz = audio_framework_source_config.sample_rate;
- LOG_ASSERT(af_hz >= sr_hz) << __func__ << " sample freq issue";
-
- int pitch = af_hz / sr_hz;
-
if (num_channels == 1) {
/* Since we always get two channels from framework, lets make it mono here
*/
std::vector<int16_t> chan_mono;
- get_mono_stream(data, chan_mono, pitch);
+ get_mono_stream(data, chan_mono);
- lc3_encode(lc3_encoder_left, (const int16_t*)chan_mono.data(), 1,
- byte_count, chan_encoded.data());
+ auto err = lc3_encode(lc3_encoder_left, (const int16_t*)chan_mono.data(),
+ 1, byte_count, chan_encoded.data());
+ if (err < 0) {
+ LOG(ERROR) << " error while encoding, error code: " << +err;
+ }
} else {
- lc3_encode(lc3_encoder_left, (const int16_t*)data.data(), 2 * pitch,
- byte_count, chan_encoded.data());
- lc3_encode(lc3_encoder_right, (const int16_t*)data.data() + 1, 2 * pitch,
+ lc3_encode(lc3_encoder_left, (const int16_t*)data.data(), 2, byte_count,
+ chan_encoded.data());
+ lc3_encode(lc3_encoder_right, (const int16_t*)data.data() + 1, 2,
byte_count, chan_encoded.data() + byte_count);
}
@@ -2058,8 +2063,21 @@ class LeAudioClientImpl : public LeAudioClient {
void SendAudioData(uint8_t* data, uint16_t size) {
/* Get only one channel for MONO microphone */
/* Gather data for channel */
+
+ if ((active_group_id_ == bluetooth::groups::kGroupUnknown) ||
+ (audio_sender_state_ != AudioState::STARTED))
+ return;
+
+ LeAudioDeviceGroup* group = aseGroups_.FindById(active_group_id_);
+ if (!group) {
+ LOG(ERROR) << __func__ << "There is no streaming group available";
+ return;
+ }
+
+ auto stream_conf = group->stream_conf;
+
uint16_t required_for_channel_byte_count =
- lc3_decoder->lc3Config.getByteCountFromBitrate(32000);
+ stream_conf.source_octets_per_codec_frame;
size_t required_byte_count = current_sink_codec_config.num_channels *
required_for_channel_byte_count;
@@ -2069,14 +2087,32 @@ class LeAudioClientImpl : public LeAudioClient {
return;
}
- uint8_t BEC_detect = 0;
- std::vector<int16_t> pcm_data_decoded(lc3_decoder->lc3Config.NF, 0);
- auto err = lc3_decoder->run(data, required_for_channel_byte_count, 0,
- pcm_data_decoded.data(),
- pcm_data_decoded.size(), BEC_detect);
+ int dt_us = current_sink_codec_config.data_interval_us;
+ int af_hz = audio_framework_sink_config.sample_rate;
+
+ int pcm_size;
+ if (dt_us == 10000) {
+ if (af_hz == 44100)
+ pcm_size = 480;
+ else
+ pcm_size = af_hz / 100;
+ } else if (dt_us == 7500) {
+ if (af_hz == 44100)
+ pcm_size = 360;
+ else
+ pcm_size = (af_hz * 3) / 400;
+ } else {
+ LOG(ERROR) << "BAD dt_us: " << dt_us;
+ return;
+ }
+
+ std::vector<int16_t> pcm_data_decoded(pcm_size, 0);
+
+ auto err = lc3_decode(lc3_decoder, data, size, pcm_data_decoded.data(),
+ 1 /* pitch */);
/* TODO: How handle failing decoding ? */
- if (err != Lc3Decoder::ERROR_FREE) {
+ if (err < 0) {
LOG(ERROR) << " error while decoding error code: "
<< static_cast<int>(err);
return;
@@ -2088,17 +2124,6 @@ class LeAudioClientImpl : public LeAudioClient {
/* TODO: What to do if not all data sinked ? */
if (written != to_write) LOG(ERROR) << __func__ << ", not all data sinked";
-
- DLOG(INFO) << __func__
- << " num of frames: " << (int)lc3_decoder->lc3Config.NF;
- }
-
- static inline Lc3Config::FrameDuration Lc3ConfigFrameDuration(
- uint32_t frame_duration_us) {
- if (frame_duration_us == LeAudioCodecConfiguration::kInterval7500Us)
- return Lc3Config::FrameDuration::d7p5ms;
- else
- return Lc3Config::FrameDuration::d10ms;
}
bool StartSendingAudio(int group_id) {
@@ -2130,14 +2155,17 @@ class LeAudioClientImpl : public LeAudioClient {
}
int dt_us = current_source_codec_config.data_interval_us;
int sr_hz = current_source_codec_config.sample_rate;
- unsigned enc_size = lc3_encoder_size(dt_us, sr_hz);
+ int af_hz = audio_framework_source_config.sample_rate;
+ unsigned enc_size = lc3_encoder_size(dt_us, af_hz);
lc3_encoder_left_mem = malloc(enc_size);
lc3_encoder_right_mem = malloc(enc_size);
- lc3_encoder_left = lc3_setup_encoder(dt_us, sr_hz, lc3_encoder_left_mem);
+ lc3_encoder_left =
+ lc3_setup_encoder(dt_us, sr_hz, af_hz, lc3_encoder_left_mem);
lc3_encoder_right =
- lc3_setup_encoder(dt_us, sr_hz, lc3_encoder_right_mem);
+ lc3_setup_encoder(dt_us, sr_hz, af_hz, lc3_encoder_right_mem);
+
} else if (CodecManager::GetInstance()->GetCodecLocation() ==
le_audio::types::CodecLocation::ADSP) {
CodecManager::GetInstance()->UpdateActiveSourceAudioConfig(
@@ -2207,12 +2235,20 @@ class LeAudioClientImpl : public LeAudioClient {
if (CodecManager::GetInstance()->GetCodecLocation() ==
le_audio::types::CodecLocation::HOST) {
- Lc3Config lc3Config(
- current_sink_codec_config.sample_rate,
- Lc3ConfigFrameDuration(current_sink_codec_config.data_interval_us),
- 1);
+ if (lc3_decoder_mem) {
+ LOG(WARNING)
+ << " The decoder instance should have been already released.";
+ free(lc3_decoder_mem);
+ lc3_decoder_mem = nullptr;
+ }
+
+ int dt_us = current_sink_codec_config.data_interval_us;
+ int sr_hz = current_sink_codec_config.sample_rate;
+ int af_hz = audio_framework_sink_config.sample_rate;
+ unsigned dec_size = lc3_decoder_size(dt_us, af_hz);
+ lc3_decoder_mem = malloc(dec_size);
- lc3_decoder = new Lc3Decoder(lc3Config);
+ lc3_decoder = lc3_setup_decoder(dt_us, sr_hz, af_hz, lc3_decoder_mem);
} else if (CodecManager::GetInstance()->GetCodecLocation() ==
le_audio::types::CodecLocation::ADSP) {
CodecManager::GetInstance()->UpdateActiveSinkAudioConfig(*stream_conf,
@@ -2235,11 +2271,10 @@ class LeAudioClientImpl : public LeAudioClient {
lc3_encoder_right_mem = nullptr;
}
- if (lc3_decoder) {
+ if (lc3_decoder_mem) {
LOG(INFO) << __func__ << " stopping sink";
-
- delete lc3_decoder;
- lc3_decoder = nullptr;
+ free(lc3_decoder_mem);
+ lc3_decoder_mem = nullptr;
}
}
@@ -2305,12 +2340,15 @@ class LeAudioClientImpl : public LeAudioClient {
leAudioDevices_.Dump(fd, bluetooth::groups::kGroupUnknown);
}
- void Cleanup(void) {
+ void Cleanup(base::Callback<void()> cleanupCb) {
if (alarm_is_scheduled(suspend_timeout_)) alarm_cancel(suspend_timeout_);
+ groupStateMachine_->Cleanup();
leAudioDevices_.Cleanup();
aseGroups_.Cleanup();
StopAudio();
if (gatt_if_) BTA_GATTC_AppDeregister(gatt_if_);
+
+ std::move(cleanupCb).Run();
}
bool UpdateConfigAndCheckIfReconfigurationIsNeeded(
@@ -3090,7 +3128,9 @@ class LeAudioClientImpl : public LeAudioClient {
lc3_encoder_t lc3_encoder_left;
lc3_encoder_t lc3_encoder_right;
- Lc3Decoder* lc3_decoder;
+ void* lc3_decoder_mem;
+ lc3_decoder_t lc3_decoder;
+
std::vector<uint8_t> encoded_data;
const void* audio_source_instance_;
const void* audio_sink_instance_;
@@ -3303,7 +3343,9 @@ LeAudioClient* LeAudioClient::Get() {
/* Initializer of main le audio implementation class and its instance */
void LeAudioClient::Initialize(
bluetooth::le_audio::LeAudioClientCallbacks* callbacks_,
- base::Closure initCb, base::Callback<bool()> hal_2_1_verifier) {
+ base::Closure initCb, base::Callback<bool()> hal_2_1_verifier,
+ const std::vector<bluetooth::le_audio::btle_audio_codec_config_t>&
+ offloading_preference) {
if (instance) {
LOG(ERROR) << "Already initialized";
return;
@@ -3337,7 +3379,7 @@ void LeAudioClient::Initialize(
instance = new LeAudioClientImpl(callbacks_, stateMachineCallbacks, initCb);
IsoManager::GetInstance()->RegisterCigCallbacks(stateMachineHciCallbacks);
- CodecManager::GetInstance()->Start();
+ CodecManager::GetInstance()->Start(offloading_preference, capabilities);
}
void LeAudioClient::DebugDump(int fd) {
@@ -3354,7 +3396,7 @@ void LeAudioClient::DebugDump(int fd) {
dprintf(fd, "\n");
}
-void LeAudioClient::Cleanup(void) {
+void LeAudioClient::Cleanup(base::Callback<void()> cleanupCb) {
if (!instance) {
LOG(ERROR) << "Not initialized";
return;
@@ -3362,7 +3404,7 @@ void LeAudioClient::Cleanup(void) {
LeAudioClientImpl* ptr = instance;
instance = nullptr;
- ptr->Cleanup();
+ ptr->Cleanup(cleanupCb);
delete ptr;
CodecManager::GetInstance()->Stop();
diff --git a/system/bta/le_audio/client_linux.cc b/system/bta/le_audio/client_linux.cc
index 309a8fee2e..9644bfdc73 100644
--- a/system/bta/le_audio/client_linux.cc
+++ b/system/bta/le_audio/client_linux.cc
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <base/callback.h>
+
#include "bta_le_audio_api.h"
class LeAudioClientImpl : public LeAudioClient {
@@ -38,9 +40,13 @@ class LeAudioClientImpl : public LeAudioClient {
void LeAudioClient::Initialize(
bluetooth::le_audio::LeAudioClientCallbacks* callbacks,
- base::Closure initCb, base::Callback<bool()> hal_2_1_verifier) {}
-void LeAudioClient::Cleanup(void) {}
+ base::Closure initCb, base::Callback<bool()> hal_2_1_verifier,
+ const std::vector<bluetooth::le_audio::btle_audio_codec_config_t>&
+ offloading_preference) {}
+void LeAudioClient::Cleanup(base::Callback<void()> cleanupCb) {}
LeAudioClient* LeAudioClient::Get(void) { return nullptr; }
void LeAudioClient::DebugDump(int fd) {}
void LeAudioClient::AddFromStorage(const RawAddress& addr, bool autoconnect) {}
bool LeAudioClient::IsLeAudioClientRunning() { return false; }
+void LeAudioClient::InitializeAudioSetConfigurationProvider(void) {}
+void LeAudioClient::CleanupAudioSetConfigurationProvider(void) {}
diff --git a/system/bta/le_audio/codec_manager.cc b/system/bta/le_audio/codec_manager.cc
index 3063d0c055..55db54430c 100644
--- a/system/bta/le_audio/codec_manager.cc
+++ b/system/bta/le_audio/codec_manager.cc
@@ -22,6 +22,7 @@
#include "osi/include/properties.h"
#include "stack/acl/acl.h"
#include "stack/include/acl_api.h"
+#include "le_audio_set_configuration_provider.h"
namespace {
@@ -29,13 +30,23 @@ using bluetooth::hci::iso_manager::kIsoDataPathHci;
using bluetooth::hci::iso_manager::kIsoDataPathPlatformDefault;
using le_audio::CodecManager;
using le_audio::types::CodecLocation;
+
+using bluetooth::le_audio::btle_audio_codec_config_t;
+using bluetooth::le_audio::btle_audio_codec_index_t;
+using le_audio::AudioSetConfigurationProvider;
+using le_audio::set_configurations::AudioSetConfiguration;
+using le_audio::set_configurations::AudioSetConfigurations;
+using le_audio::set_configurations::SetConfiguration;
+
} // namespace
namespace le_audio {
struct codec_manager_impl {
public:
- codec_manager_impl() {
+ codec_manager_impl(
+ const std::vector<btle_audio_codec_config_t>& offloading_preference,
+ const std::vector<AudioSetConfiguration>& adsp_capabilities) {
offload_enable_ = osi_property_get_bool(
"ro.bluetooth.leaudio_offload.supported", false) &&
osi_property_get_bool(
@@ -60,6 +71,7 @@ struct codec_manager_impl {
kIsoDataPathPlatformDefault, {});
btm_configure_data_path(btm_data_direction::CONTROLLER_TO_HOST,
kIsoDataPathPlatformDefault, {});
+ UpdateOffloadCapability(offloading_preference, adsp_capabilities);
SetCodecLocation(CodecLocation::ADSP);
}
~codec_manager_impl() {
@@ -73,7 +85,7 @@ struct codec_manager_impl {
CodecLocation GetCodecLocation(void) const { return codec_location_; }
void UpdateActiveSourceAudioConfig(
- const le_audio::stream_configuration& stream_conf, uint16_t delay) {
+ const le_audio::stream_configuration& stream_conf, uint16_t delay_ms) {
if (stream_conf.sink_streams.empty()) return;
sink_config.stream_map = std::move(stream_conf.sink_streams);
@@ -86,12 +98,12 @@ struct codec_manager_impl {
// TODO: set the default value 1 for now, would change it if we need more
// configuration
sink_config.blocks_per_sdu = 1;
- sink_config.peer_delay = delay;
+ sink_config.peer_delay_ms = delay_ms;
LeAudioClientAudioSource::UpdateAudioConfigToHal(sink_config);
}
void UpdateActiveSinkAudioConfig(
- const le_audio::stream_configuration& stream_conf, uint16_t delay) {
+ const le_audio::stream_configuration& stream_conf, uint16_t delay_ms) {
if (stream_conf.source_streams.empty()) return;
source_config.stream_map = std::move(stream_conf.source_streams);
@@ -104,27 +116,167 @@ struct codec_manager_impl {
// TODO: set the default value 1 for now, would change it if we need more
// configuration
source_config.blocks_per_sdu = 1;
- source_config.peer_delay = delay;
+ source_config.peer_delay_ms = delay_ms;
LeAudioClientAudioSink::UpdateAudioConfigToHal(source_config);
}
+ const AudioSetConfigurations* GetOffloadCodecConfig(
+ types::LeAudioContextType ctx_type) {
+ return &context_type_offload_config_map_[ctx_type];
+ }
+
private:
void SetCodecLocation(CodecLocation location) {
if (offload_enable_ == false) return;
codec_location_ = location;
}
+
+ bool IsLc3ConfigMatched(
+ const set_configurations::CodecCapabilitySetting& adsp_config,
+ const set_configurations::CodecCapabilitySetting& target_config) {
+ if (adsp_config.id.coding_format != types::kLeAudioCodingFormatLC3 ||
+ target_config.id.coding_format != types::kLeAudioCodingFormatLC3) {
+ return false;
+ }
+
+ const types::LeAudioLc3Config adsp_lc3_config =
+ std::get<types::LeAudioLc3Config>(adsp_config.config);
+ const types::LeAudioLc3Config target_lc3_config =
+ std::get<types::LeAudioLc3Config>(target_config.config);
+
+ if (adsp_lc3_config.sampling_frequency !=
+ target_lc3_config.sampling_frequency ||
+ adsp_lc3_config.frame_duration != target_lc3_config.frame_duration ||
+ adsp_lc3_config.channel_count != target_lc3_config.channel_count ||
+ adsp_lc3_config.octets_per_codec_frame !=
+ target_lc3_config.octets_per_codec_frame) {
+ return false;
+ }
+
+ return true;
+ }
+
+ bool IsSetConfigurationMatched(const SetConfiguration& software_set_config,
+ const SetConfiguration& adsp_set_config) {
+ // Skip the check of stategry and ase_cnt due to ADSP doesn't have the info
+ return (
+ software_set_config.direction == adsp_set_config.direction &&
+ software_set_config.device_cnt == adsp_set_config.device_cnt &&
+ IsLc3ConfigMatched(software_set_config.codec, adsp_set_config.codec));
+ }
+
+ bool IsAudioSetConfigurationMatched(
+ const AudioSetConfiguration* software_audio_set_conf,
+ std::unordered_set<uint8_t>& offload_preference_set,
+ const std::vector<AudioSetConfiguration>& adsp_capabilities) {
+ if (software_audio_set_conf->confs.empty()) {
+ return false;
+ }
+
+ std::unordered_map<uint8_t, const SetConfiguration&>
+ software_set_conf_direction_map;
+
+ for (auto& software_set_conf : software_audio_set_conf->confs) {
+ // Checks offload preference supports the codec
+ if (offload_preference_set.find(
+ software_set_conf.codec.id.coding_format) ==
+ offload_preference_set.end()) {
+ return false;
+ }
+ software_set_conf_direction_map.emplace(software_set_conf.direction,
+ software_set_conf);
+ }
+
+ // Checks any of offload config matches the input audio set config
+ for (const auto& adsp_audio_set_conf : adsp_capabilities) {
+ if (adsp_audio_set_conf.confs.size() !=
+ software_audio_set_conf->confs.size()) {
+ continue;
+ }
+
+ size_t match_cnt = 0;
+
+ for (auto& adsp_set_conf : adsp_audio_set_conf.confs) {
+ auto it = software_set_conf_direction_map.find(adsp_set_conf.direction);
+
+ if (it == software_set_conf_direction_map.end()) {
+ continue;
+ }
+
+ if (IsSetConfigurationMatched(it->second, adsp_set_conf)) {
+ match_cnt++;
+ }
+ }
+
+ if (match_cnt == software_set_conf_direction_map.size()) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ void UpdateOffloadCapability(
+ const std::vector<btle_audio_codec_config_t>& offloading_preference,
+ const std::vector<AudioSetConfiguration>& adsp_capabilities) {
+ LOG(INFO) << __func__;
+ std::unordered_set<uint8_t> offload_preference_set;
+
+ if (AudioSetConfigurationProvider::Get() == nullptr) {
+ LOG(ERROR) << __func__ << " Audio set configuration provider is not available.";
+ return;
+ }
+
+ for (auto codec : offloading_preference) {
+ auto it = btle_audio_codec_type_map_.find(codec.codec_type);
+
+ if (it != btle_audio_codec_type_map_.end()) {
+ offload_preference_set.insert(it->second);
+ }
+ }
+
+ for (types::LeAudioContextType ctx_type :
+ types::kLeAudioContextAllTypesArray) {
+ // Gets the software supported context type and the corresponding config
+ // priority
+ const AudioSetConfigurations* software_audio_set_confs =
+ AudioSetConfigurationProvider::Get()->GetConfigurations(ctx_type);
+
+ for (const auto& software_audio_set_conf : *software_audio_set_confs) {
+ if (IsAudioSetConfigurationMatched(software_audio_set_conf,
+ offload_preference_set,
+ adsp_capabilities)) {
+ LOG(INFO) << "Offload supported conf, context type: " << (int)ctx_type
+ << ", settings -> " << software_audio_set_conf->name;
+ context_type_offload_config_map_[ctx_type].push_back(
+ software_audio_set_conf);
+ }
+ }
+ }
+ }
+
CodecLocation codec_location_ = CodecLocation::HOST;
bool offload_enable_ = false;
le_audio::offload_config sink_config;
le_audio::offload_config source_config;
+ std::unordered_map<types::LeAudioContextType, AudioSetConfigurations>
+ context_type_offload_config_map_;
+ std::unordered_map<btle_audio_codec_index_t, uint8_t>
+ btle_audio_codec_type_map_ = {
+ {::bluetooth::le_audio::LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
+ types::kLeAudioCodingFormatLC3}};
};
struct CodecManager::impl {
impl(const CodecManager& codec_manager) : codec_manager_(codec_manager) {}
- void Start() {
+ void Start(
+ const std::vector<btle_audio_codec_config_t>& offloading_preference,
+ const std::vector<set_configurations::AudioSetConfiguration>&
+ adsp_capabilities) {
LOG_ASSERT(!codec_manager_impl_);
- codec_manager_impl_ = std::make_unique<codec_manager_impl>();
+ codec_manager_impl_ = std::make_unique<codec_manager_impl>(
+ offloading_preference, adsp_capabilities);
}
void Stop() {
@@ -140,8 +292,12 @@ struct CodecManager::impl {
CodecManager::CodecManager() : pimpl_(std::make_unique<impl>(*this)) {}
-void CodecManager::Start() {
- if (!pimpl_->IsRunning()) pimpl_->Start();
+void CodecManager::Start(
+ const std::vector<btle_audio_codec_config_t>& offloading_preference,
+ const std::vector<set_configurations::AudioSetConfiguration>&
+ adsp_capabilities) {
+ if (!pimpl_->IsRunning())
+ pimpl_->Start(offloading_preference, adsp_capabilities);
}
void CodecManager::Stop() {
@@ -157,17 +313,26 @@ types::CodecLocation CodecManager::GetCodecLocation(void) const {
}
void CodecManager::UpdateActiveSourceAudioConfig(
- const stream_configuration& stream_conf, uint16_t delay) {
+ const stream_configuration& stream_conf, uint16_t delay_ms) {
if (pimpl_->IsRunning())
pimpl_->codec_manager_impl_->UpdateActiveSourceAudioConfig(stream_conf,
- delay);
+ delay_ms);
}
void CodecManager::UpdateActiveSinkAudioConfig(
- const stream_configuration& stream_conf, uint16_t delay) {
+ const stream_configuration& stream_conf, uint16_t delay_ms) {
if (pimpl_->IsRunning())
pimpl_->codec_manager_impl_->UpdateActiveSinkAudioConfig(stream_conf,
- delay);
+ delay_ms);
+}
+
+const AudioSetConfigurations* CodecManager::GetOffloadCodecConfig(
+ types::LeAudioContextType ctx_type) {
+ if (pimpl_->IsRunning()) {
+ return pimpl_->codec_manager_impl_->GetOffloadCodecConfig(ctx_type);
+ }
+
+ return nullptr;
}
} // namespace le_audio
diff --git a/system/bta/le_audio/codec_manager.h b/system/bta/le_audio/codec_manager.h
index 84e2948aa9..4c02563b34 100644
--- a/system/bta/le_audio/codec_manager.h
+++ b/system/bta/le_audio/codec_manager.h
@@ -27,7 +27,7 @@ struct offload_config {
uint32_t frame_duration;
uint16_t octets_per_frame;
uint8_t blocks_per_sdu;
- uint16_t peer_delay;
+ uint16_t peer_delay_ms;
};
class CodecManager {
@@ -38,13 +38,19 @@ class CodecManager {
static CodecManager* instance = new CodecManager();
return instance;
}
- void Start(void);
+ void Start(
+ const std::vector<bluetooth::le_audio::btle_audio_codec_config_t>&
+ offloading_preference,
+ const std::vector<::le_audio::set_configurations::AudioSetConfiguration>&
+ adsp_capabilities);
void Stop(void);
virtual types::CodecLocation GetCodecLocation(void) const;
virtual void UpdateActiveSourceAudioConfig(
- const stream_configuration& stream_conf, uint16_t delay);
+ const stream_configuration& stream_conf, uint16_t delay_ms);
virtual void UpdateActiveSinkAudioConfig(
- const stream_configuration& stream_conf, uint16_t delay);
+ const stream_configuration& stream_conf, uint16_t delay_ms);
+ const ::le_audio::set_configurations::AudioSetConfigurations*
+ GetOffloadCodecConfig(::le_audio::types::LeAudioContextType ctx_type);
private:
struct impl;
diff --git a/system/bta/le_audio/devices.cc b/system/bta/le_audio/devices.cc
index 40588f6f45..7ebae5e26f 100644
--- a/system/bta/le_audio/devices.cc
+++ b/system/bta/le_audio/devices.cc
@@ -28,6 +28,7 @@
#include "btm_iso_api_types.h"
#include "client_audio.h"
#include "device/include/controller.h"
+#include "le_audio_set_configuration_provider.h"
using bluetooth::hci::kIsoCigFramingFramed;
using bluetooth::hci::kIsoCigFramingUnframed;
@@ -35,6 +36,7 @@ using bluetooth::hci::kIsoCigPackingSequential;
using bluetooth::hci::kIsoCigPhy1M;
using bluetooth::hci::kIsoCigPhy2M;
using bluetooth::hci::iso_manager::kIsoSca0To20Ppm;
+using le_audio::AudioSetConfigurationProvider;
using le_audio::set_configurations::CodecCapabilitySetting;
using le_audio::types::ase;
using le_audio::types::AseState;
@@ -104,7 +106,10 @@ void LeAudioDeviceGroup::Deactivate(void) {
}
LeAudioDevice* LeAudioDeviceGroup::GetFirstDevice(void) {
- return (leAudioDevices_.front().lock()).get();
+ auto d = leAudioDevices_.front();
+ if (d.expired()) return nullptr;
+
+ return (d.lock()).get();
}
LeAudioDevice* LeAudioDeviceGroup::GetFirstDeviceWithActiveContext(
@@ -1114,7 +1119,7 @@ const set_configurations::AudioSetConfiguration*
LeAudioDeviceGroup::FindFirstSupportedConfiguration(
LeAudioContextType context_type) {
const set_configurations::AudioSetConfigurations* confs =
- set_configurations::get_confs_by_type(context_type);
+ AudioSetConfigurationProvider::Get()->GetConfigurations(context_type);
DLOG(INFO) << __func__ << " context type: " << (int)context_type
<< " number of connected devices: " << NumOfConnected();
diff --git a/system/bta/le_audio/devices_test.cc b/system/bta/le_audio/devices_test.cc
index 888fad83b9..bb8a939091 100644
--- a/system/bta/le_audio/devices_test.cc
+++ b/system/bta/le_audio/devices_test.cc
@@ -21,6 +21,7 @@
#include <gtest/gtest.h>
#include "btm_api_mock.h"
+#include "le_audio_set_configuration_provider.h"
#include "le_audio_types.h"
#include "mock_controller.h"
#include "stack/btm/btm_int_types.h"
@@ -380,6 +381,7 @@ class LeAudioAseConfigurationTest : public Test {
group_ = new LeAudioDeviceGroup(group_id_);
bluetooth::manager::SetMockBtmInterface(&btm_interface_);
controller::SetMockControllerInterface(&controller_interface_);
+ ::le_audio::AudioSetConfigurationProvider::Initialize();
}
void TearDown() override {
@@ -387,6 +389,7 @@ class LeAudioAseConfigurationTest : public Test {
bluetooth::manager::SetMockBtmInterface(nullptr);
devices_.clear();
delete group_;
+ ::le_audio::AudioSetConfigurationProvider::Cleanup();
}
LeAudioDevice* AddTestDevice(int snk_ase_num, int src_ase_num,
@@ -505,7 +508,9 @@ class LeAudioAseConfigurationTest : public Test {
void TestGroupAseConfiguration(LeAudioContextType context_type,
TestGroupAseConfigurationData* data,
uint8_t data_size) {
- const auto* configurations = get_confs_by_type(context_type);
+ const auto* configurations =
+ ::le_audio::AudioSetConfigurationProvider::Get()->GetConfigurations(
+ context_type);
for (const auto& audio_set_conf : *configurations) {
// the configuration should fail if there are no active ases expected
bool success_expected = data_size > 0;
@@ -854,8 +859,14 @@ TEST_F(LeAudioAseConfigurationTest, test_reconnection_media) {
{right, kLeAudioCodecLC3ChannelCountSingleChannel,
kLeAudioCodecLC3ChannelCountSingleChannel, 1, 0}};
- TestSingleAseConfiguration(LeAudioContextType::MEDIA, data, 2,
- &kDualDev_OneChanStereoSnk_48_4);
+ auto all_configurations =
+ ::le_audio::AudioSetConfigurationProvider::Get()->GetConfigurations(
+ LeAudioContextType::MEDIA);
+ ASSERT_NE(nullptr, all_configurations);
+ ASSERT_NE(all_configurations->end(), all_configurations->begin());
+ auto configuration = *all_configurations->begin();
+
+ TestSingleAseConfiguration(LeAudioContextType::MEDIA, data, 2, configuration);
SetCisInformationToActiveAse();
@@ -871,9 +882,6 @@ TEST_F(LeAudioAseConfigurationTest, test_reconnection_media) {
::le_audio::types::AudioLocations group_src_audio_location =
*ase->codec_config.audio_channel_allocation;
- /* Get known requirement*/
- auto* configuration = &kDualDev_OneChanStereoSnk_48_4;
-
/* Get entry for the sink direction and use it to set configuration */
for (auto& ent : configuration->confs) {
if (ent.direction == ::le_audio::types::kLeAudioDirectionSink) {
diff --git a/system/bta/le_audio/hal_verifier.cc b/system/bta/le_audio/hal_verifier.cc
index 5eb6b8004a..2367593a45 100644
--- a/system/bta/le_audio/hal_verifier.cc
+++ b/system/bta/le_audio/hal_verifier.cc
@@ -23,6 +23,11 @@ bool LeAudioHalVerifier::SupportsLeAudio() {
}
bool LeAudioHalVerifier::SupportsLeAudioHardwareOffload() {
- return bluetooth::audio::HalVersionManager::GetHalVersion() >
- bluetooth::audio::BluetoothAudioHalVersion::VERSION_2_1;
+ return bluetooth::audio::HalVersionManager::GetHalTransport() ==
+ bluetooth::audio::BluetoothAudioHalTransport::AIDL;
+}
+
+bool LeAudioHalVerifier::SupportsLeAudioBroadcast() {
+ return bluetooth::audio::HalVersionManager::GetHalTransport() ==
+ bluetooth::audio::BluetoothAudioHalTransport::AIDL;
}
diff --git a/system/bta/le_audio/hal_verifier_linux.cc b/system/bta/le_audio/hal_verifier_linux.cc
index 2da71ef329..3318291eb9 100644
--- a/system/bta/le_audio/hal_verifier_linux.cc
+++ b/system/bta/le_audio/hal_verifier_linux.cc
@@ -18,3 +18,4 @@
bool LeAudioHalVerifier::SupportsLeAudio() { return false; }
bool LeAudioHalVerifier::SupportsLeAudioHardwareOffload() { return false; }
+bool LeAudioHalVerifier::SupportsLeAudioBroadcast() { return false; }
diff --git a/system/bta/le_audio/le_audio_client_test.cc b/system/bta/le_audio/le_audio_client_test.cc
index 13f8067ad9..4aae9493fc 100644
--- a/system/bta/le_audio/le_audio_client_test.cc
+++ b/system/bta/le_audio/le_audio_client_test.cc
@@ -33,6 +33,7 @@
#include "fake_osi.h"
#include "gatt/database_builder.h"
#include "hardware/bt_gatt_types.h"
+#include "le_audio_set_configuration_provider.h"
#include "le_audio_types.h"
#include "mock_controller.h"
#include "mock_csis_client.h"
@@ -264,7 +265,9 @@ class UnicastTestNoInit : public Test {
base::Unretained(this->gatt_callback), event_data));
}
- void InjectDisconnectedEvent(uint16_t conn_id) {
+ void InjectDisconnectedEvent(
+ uint16_t conn_id,
+ tGATT_DISCONN_REASON reason = GATT_CONN_TERMINATE_LOCAL_HOST) {
ASSERT_NE(conn_id, GATT_INVALID_CONN_ID);
ASSERT_NE(peer_devices.count(conn_id), 0u);
@@ -273,7 +276,7 @@ class UnicastTestNoInit : public Test {
.conn_id = conn_id,
.client_if = gatt_if,
.remote_bda = peer_devices.at(conn_id)->addr,
- .reason = GATT_CONN_TERMINATE_PEER_USER,
+ .reason = reason,
};
peer_devices.at(conn_id)->connected = false;
@@ -715,6 +718,7 @@ class UnicastTestNoInit : public Test {
SetUpMockGroups();
SetUpMockGatt();
+ le_audio::AudioSetConfigurationProvider::Initialize();
ASSERT_FALSE(LeAudioClient::IsLeAudioClientRunning());
}
@@ -730,10 +734,13 @@ class UnicastTestNoInit : public Test {
if (LeAudioClient::IsLeAudioClientRunning()) {
EXPECT_CALL(mock_gatt_interface_, AppDeregister(gatt_if)).Times(1);
- LeAudioClient::Cleanup();
+ LeAudioClient::Cleanup(base::DoNothing());
ASSERT_FALSE(LeAudioClient::IsLeAudioClientRunning());
}
+ if (le_audio::AudioSetConfigurationProvider::Get())
+ le_audio::AudioSetConfigurationProvider::Cleanup();
+
iso_manager_->Stop();
}
@@ -1627,6 +1634,8 @@ class UnicastTest : public UnicastTestNoInit {
EXPECT_CALL(mock_hal_2_1_verifier, Call()).Times(1);
EXPECT_CALL(mock_storage_load, Call()).Times(1);
+ std::vector<::bluetooth::le_audio::btle_audio_codec_config_t>
+ framework_encode_preference;
BtaAppRegisterCallback app_register_callback;
EXPECT_CALL(mock_gatt_interface_, AppRegister(_, _, _))
.WillOnce(DoAll(SaveArg<0>(&gatt_callback),
@@ -1636,7 +1645,8 @@ class UnicastTest : public UnicastTestNoInit {
base::Bind([](MockFunction<void()>* foo) { foo->Call(); },
&mock_storage_load),
base::Bind([](MockFunction<bool()>* foo) { return foo->Call(); },
- &mock_hal_2_1_verifier));
+ &mock_hal_2_1_verifier),
+ framework_encode_preference);
SyncOnMainLoop();
ASSERT_TRUE(gatt_callback);
@@ -1675,6 +1685,8 @@ TEST_F(UnicastTestNoInit, InitializeNoHal_2_1) {
ON_CALL(mock_gatt_interface_, AppRegister(_, _, _))
.WillByDefault(DoAll(SaveArg<0>(&gatt_callback),
SaveArg<1>(&app_register_callback)));
+ std::vector<::bluetooth::le_audio::btle_audio_codec_config_t>
+ framework_encode_preference;
EXPECT_DEATH(
LeAudioClient::Initialize(
@@ -1682,7 +1694,8 @@ TEST_F(UnicastTestNoInit, InitializeNoHal_2_1) {
base::Bind([](MockFunction<void()>* foo) { foo->Call(); },
&mock_storage_load),
base::Bind([](MockFunction<bool()>* foo) { return foo->Call(); },
- &mock_hal_2_1_verifier)),
+ &mock_hal_2_1_verifier),
+ framework_encode_preference),
", LE Audio Client requires Bluetooth Audio HAL V2.1 at least. Either "
"disable LE Audio Profile, or update your HAL");
}
@@ -1769,6 +1782,29 @@ TEST_F(UnicastTest, ConnectDisconnectOneEarbud) {
DisconnectLeAudio(test_address0, 1);
}
+/* same as above case except the disconnect is initiated by remote */
+TEST_F(UnicastTest, ConnectRemoteDisconnectOneEarbud) {
+ const RawAddress test_address0 = GetTestAddress(0);
+ SetSampleDatabaseEarbudsValid(1, test_address0,
+ codec_spec_conf::kLeAudioLocationStereo,
+ codec_spec_conf::kLeAudioLocationStereo);
+ EXPECT_CALL(mock_client_callbacks_,
+ OnConnectionState(ConnectionState::CONNECTED, test_address0))
+ .Times(1);
+ ConnectLeAudio(test_address0);
+ EXPECT_CALL(mock_client_callbacks_,
+ OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
+ .Times(1);
+ /* For remote disconnection, expect stack to try background re-connect */
+ EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, false, _))
+ .Times(1);
+ global_conn_id = 1; /* Reset to keep conn_id same during re-connect */
+ EXPECT_CALL(mock_client_callbacks_,
+ OnConnectionState(ConnectionState::CONNECTED, test_address0))
+ .Times(1);
+ InjectDisconnectedEvent(1, GATT_CONN_TERMINATE_PEER_USER);
+}
+
TEST_F(UnicastTest, ConnectTwoEarbudsCsisGrouped) {
uint8_t group_size = 2;
int group_id = 2;
@@ -1899,6 +1935,9 @@ TEST_F(UnicastTestNoInit, LoadStoredEarbudsCsisGrouped) {
.WillByDefault(
DoAll(SetArgPointee<1>(BTM_SEC_FLAG_ENCRYPTED), Return(true)));
+ std::vector<::bluetooth::le_audio::btle_audio_codec_config_t>
+ framework_encode_preference;
+
// Initialize
BtaAppRegisterCallback app_register_callback;
ON_CALL(mock_gatt_interface_, AppRegister(_, _, _))
@@ -1909,7 +1948,8 @@ TEST_F(UnicastTestNoInit, LoadStoredEarbudsCsisGrouped) {
base::Bind([](MockFunction<void()>* foo) { foo->Call(); },
&mock_storage_load),
base::Bind([](MockFunction<bool()>* foo) { return foo->Call(); },
- &mock_hal_2_1_verifier));
+ &mock_hal_2_1_verifier),
+ framework_encode_preference);
if (app_register_callback) app_register_callback.Run(gatt_if, GATT_SUCCESS);
// We need to wait for the storage callback before verifying stuff
@@ -1991,12 +2031,15 @@ TEST_F(UnicastTestNoInit, LoadStoredEarbudsCsisGroupedDifferently) {
ON_CALL(mock_gatt_interface_, AppRegister(_, _, _))
.WillByDefault(DoAll(SaveArg<0>(&gatt_callback),
SaveArg<1>(&app_register_callback)));
+ std::vector<::bluetooth::le_audio::btle_audio_codec_config_t>
+ framework_encode_preference;
LeAudioClient::Initialize(
&mock_client_callbacks_,
base::Bind([](MockFunction<void()>* foo) { foo->Call(); },
&mock_storage_load),
base::Bind([](MockFunction<bool()>* foo) { return foo->Call(); },
- &mock_hal_2_1_verifier));
+ &mock_hal_2_1_verifier),
+ framework_encode_preference);
if (app_register_callback) app_register_callback.Run(gatt_if, GATT_SUCCESS);
// We need to wait for the storage callback before verifying stuff
diff --git a/system/bta/le_audio/le_audio_set_configuration_provider.cc b/system/bta/le_audio/le_audio_set_configuration_provider.cc
new file mode 100644
index 0000000000..1ffc042530
--- /dev/null
+++ b/system/bta/le_audio/le_audio_set_configuration_provider.cc
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2022 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 "le_audio_set_configuration_provider.h"
+
+#include "bta_le_audio_api.h"
+
+void LeAudioClient::InitializeAudioSetConfigurationProvider(void) {
+ le_audio::AudioSetConfigurationProvider::Initialize();
+}
+
+void LeAudioClient::CleanupAudioSetConfigurationProvider(void) {
+ le_audio::AudioSetConfigurationProvider::Cleanup();
+}
diff --git a/system/bta/le_audio/le_audio_set_configuration_provider.h b/system/bta/le_audio/le_audio_set_configuration_provider.h
new file mode 100644
index 0000000000..679135942e
--- /dev/null
+++ b/system/bta/le_audio/le_audio_set_configuration_provider.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2022 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 "le_audio_types.h"
+
+namespace le_audio {
+
+/* Audio set configurations provider interface. */
+class AudioSetConfigurationProvider {
+ public:
+ AudioSetConfigurationProvider();
+ virtual ~AudioSetConfigurationProvider() = default;
+ static AudioSetConfigurationProvider* Get();
+ static void Initialize();
+ static void Cleanup();
+ virtual const set_configurations::AudioSetConfigurations* GetConfigurations(
+ ::le_audio::types::LeAudioContextType content_type) const;
+
+ private:
+ struct impl;
+ std::unique_ptr<impl> pimpl_;
+};
+
+} // namespace le_audio
diff --git a/system/bta/le_audio/le_audio_set_configuration_provider_json.cc b/system/bta/le_audio/le_audio_set_configuration_provider_json.cc
new file mode 100644
index 0000000000..b5d55b98b9
--- /dev/null
+++ b/system/bta/le_audio/le_audio_set_configuration_provider_json.cc
@@ -0,0 +1,452 @@
+/*
+ * Copyright (c) 2022 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_set_configurations_generated.h"
+#include "audio_set_scenarios_generated.h"
+#include "codec_manager.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/util.h"
+#include "le_audio_set_configuration_provider.h"
+#include "osi/include/log.h"
+
+using le_audio::set_configurations::AudioSetConfiguration;
+using le_audio::set_configurations::AudioSetConfigurations;
+using le_audio::set_configurations::CodecCapabilitySetting;
+using le_audio::set_configurations::LeAudioCodecIdLc3;
+using le_audio::set_configurations::SetConfiguration;
+using le_audio::types::LeAudioContextType;
+
+namespace le_audio {
+using ::le_audio::CodecManager;
+
+#ifdef OS_ANDROID
+static const std::vector<
+ std::pair<const char* /*schema*/, const char* /*content*/>>
+ kLeAudioSetConfigs = {
+ {"/system/etc/bluetooth/le_audio/audio_set_configurations.bfbs",
+ "/system/etc/bluetooth/le_audio/audio_set_configurations.json"}};
+static const std::vector<
+ std::pair<const char* /*schema*/, const char* /*content*/>>
+ kLeAudioSetScenarios = {
+ {"/system/etc/bluetooth/le_audio/audio_set_scenarios.bfbs",
+ "/system/etc/bluetooth/le_audio/audio_set_scenarios.json"}};
+#else
+static const std::vector<
+ std::pair<const char* /*schema*/, const char* /*content*/>>
+ kLeAudioSetConfigs = {
+ {"audio_set_configurations.bfbs", "audio_set_configurations.json"}};
+static const std::vector<
+ std::pair<const char* /*schema*/, const char* /*content*/>>
+ kLeAudioSetScenarios = {
+ {"audio_set_scenarios.bfbs", "audio_set_scenarios.json"}};
+#endif
+
+/** Provides a set configurations for the given context type */
+struct AudioSetConfigurationProviderJson {
+ AudioSetConfigurationProviderJson() {
+ ASSERT_LOG(LoadContent(kLeAudioSetConfigs, kLeAudioSetScenarios),
+ ": Unable to load le audio set configuration files.");
+ }
+
+ const AudioSetConfigurations* GetConfigurationsByContextType(
+ LeAudioContextType context_type) const {
+ if (context_configurations_.count(context_type))
+ return &context_configurations_.at(context_type);
+
+ LOG_WARN(": No predefined scenario for the context %d was found.",
+ (int)context_type);
+
+ auto fallback_scenario = "Default";
+ context_type = ScenarioToContextType(fallback_scenario);
+
+ if (context_configurations_.count(context_type)) {
+ LOG_WARN(": Using %s scenario by default.", fallback_scenario);
+ return &context_configurations_.at(context_type);
+ }
+
+ LOG_ERROR(
+ ": No fallback configuration for the 'Default' scenario or"
+ " no valid audio set configurations loaded at all.");
+ return nullptr;
+ };
+
+ private:
+ /* Codec configurations */
+ std::map<std::string, const AudioSetConfiguration> configurations_;
+
+ /* Maps of context types to a set of configuration structs */
+ std::map<::le_audio::types::LeAudioContextType, AudioSetConfigurations>
+ context_configurations_;
+
+ static const bluetooth::le_audio::CodecSpecificConfiguration*
+ LookupCodecSpecificParam(
+ const flatbuffers::Vector<
+ flatbuffers::Offset<bluetooth::le_audio::CodecSpecificConfiguration>>*
+ flat_codec_specific_params,
+ bluetooth::le_audio::CodecSpecificLtvGenericTypes type) {
+ auto it = std::find_if(
+ flat_codec_specific_params->cbegin(),
+ flat_codec_specific_params->cend(),
+ [&type](const auto& csc) { return (csc->type() == type); });
+ return (it != flat_codec_specific_params->cend()) ? *it : nullptr;
+ }
+
+ static CodecCapabilitySetting CodecCapabilitySettingFromFlat(
+ const bluetooth::le_audio::CodecId* flat_codec_id,
+ const flatbuffers::Vector<
+ flatbuffers::Offset<bluetooth::le_audio::CodecSpecificConfiguration>>*
+ flat_codec_specific_params) {
+ CodecCapabilitySetting codec;
+
+ /* Cache the le_audio::types::CodecId type value */
+ codec.id = types::LeAudioCodecId({
+ .coding_format = flat_codec_id->coding_format(),
+ .vendor_company_id = flat_codec_id->vendor_company_id(),
+ .vendor_codec_id = flat_codec_id->vendor_codec_id(),
+ });
+
+ /* Cache the types::LeAudioLc3Config type value */
+ uint8_t sampling_frequency = 0;
+ uint8_t frame_duration = 0;
+ uint32_t audio_channel_allocation = 0;
+ uint16_t octets_per_codec_frame = 0;
+ uint8_t codec_frames_blocks_per_sdu = 0;
+
+ auto param = LookupCodecSpecificParam(
+ flat_codec_specific_params,
+ bluetooth::le_audio::
+ CodecSpecificLtvGenericTypes_SUPPORTED_SAMPLING_FREQUENCY);
+ if (param) {
+ ASSERT_LOG((param->compound_value()->value()->size() == 1),
+ " Invalid compound value length: %d",
+ param->compound_value()->value()->size());
+ auto ptr = param->compound_value()->value()->data();
+ STREAM_TO_UINT8(sampling_frequency, ptr);
+ }
+
+ param = LookupCodecSpecificParam(
+ flat_codec_specific_params,
+ bluetooth::le_audio::
+ CodecSpecificLtvGenericTypes_SUPPORTED_FRAME_DURATION);
+ if (param) {
+ LOG_ASSERT(param->compound_value()->value()->size() == 1)
+ << " Invalid compound value length: "
+ << param->compound_value()->value()->size();
+ auto ptr = param->compound_value()->value()->data();
+ STREAM_TO_UINT8(frame_duration, ptr);
+ }
+
+ param = LookupCodecSpecificParam(
+ flat_codec_specific_params,
+ bluetooth::le_audio::
+ CodecSpecificLtvGenericTypes_SUPPORTED_AUDIO_CHANNEL_ALLOCATION);
+ if (param) {
+ ASSERT_LOG((param->compound_value()->value()->size() == 4),
+ " Invalid compound value length %d",
+ param->compound_value()->value()->size());
+ auto ptr = param->compound_value()->value()->data();
+ STREAM_TO_UINT32(audio_channel_allocation, ptr);
+ }
+
+ param = LookupCodecSpecificParam(
+ flat_codec_specific_params,
+ bluetooth::le_audio::
+ CodecSpecificLtvGenericTypes_SUPPORTED_OCTETS_PER_CODEC_FRAME);
+ if (param) {
+ ASSERT_LOG((param->compound_value()->value()->size() == 2),
+ " Invalid compound value length %d",
+ param->compound_value()->value()->size());
+ auto ptr = param->compound_value()->value()->data();
+ STREAM_TO_UINT16(octets_per_codec_frame, ptr);
+ }
+
+ param = LookupCodecSpecificParam(
+ flat_codec_specific_params,
+ bluetooth::le_audio::
+ CodecSpecificLtvGenericTypes_SUPPORTED_CODEC_FRAME_BLOCKS_PER_SDU);
+ if (param) {
+ ASSERT_LOG((param->compound_value()->value()->size() == 1),
+ " Invalid compound value length %d",
+ param->compound_value()->value()->size());
+ auto ptr = param->compound_value()->value()->data();
+ STREAM_TO_UINT8(codec_frames_blocks_per_sdu, ptr);
+ }
+
+ codec.config = types::LeAudioLc3Config({
+ .sampling_frequency = sampling_frequency,
+ .frame_duration = frame_duration,
+ .octets_per_codec_frame = octets_per_codec_frame,
+ .codec_frames_blocks_per_sdu = codec_frames_blocks_per_sdu,
+ .channel_count =
+ (uint8_t)std::bitset<32>(audio_channel_allocation).count(),
+ .audio_channel_allocation = audio_channel_allocation,
+ });
+ return codec;
+ }
+
+ SetConfiguration SetConfigurationFromFlatSubconfig(
+ const bluetooth::le_audio::AudioSetSubConfiguration* flat_subconfig) {
+ auto strategy_int =
+ static_cast<int>(flat_subconfig->configuration_strategy());
+
+ bool valid_strategy =
+ (strategy_int >=
+ (int)types::LeAudioConfigurationStrategy::MONO_ONE_CIS_PER_DEVICE) &&
+ strategy_int < (int)types::LeAudioConfigurationStrategy::RFU;
+
+ types::LeAudioConfigurationStrategy strategy =
+ valid_strategy
+ ? static_cast<types::LeAudioConfigurationStrategy>(strategy_int)
+ : types::LeAudioConfigurationStrategy::RFU;
+
+ return SetConfiguration(
+ flat_subconfig->direction(), flat_subconfig->device_cnt(),
+ flat_subconfig->ase_cnt(),
+ CodecCapabilitySettingFromFlat(flat_subconfig->codec_id(),
+ flat_subconfig->codec_configuration()),
+ strategy);
+ }
+
+ AudioSetConfiguration AudioSetConfigurationFromFlat(
+ const bluetooth::le_audio::AudioSetConfiguration* flat_cfg) {
+ std::vector<SetConfiguration> subconfigs;
+ if (flat_cfg->subconfigurations()) {
+ /* Load subconfigurations */
+ for (auto subconfig : *flat_cfg->subconfigurations()) {
+ subconfigs.push_back(SetConfigurationFromFlatSubconfig(subconfig));
+ }
+
+ } else {
+ LOG_ERROR("Configuration '%s' has no valid subconfigurations.",
+ flat_cfg->name()->c_str());
+ }
+
+ return AudioSetConfiguration({flat_cfg->name()->c_str(), subconfigs});
+ }
+
+ bool LoadConfigurationsFromFiles(const char* schema_file,
+ const char* content_file) {
+ flatbuffers::Parser configurations_parser_;
+ std::string configurations_schema_binary_content;
+ bool ok = flatbuffers::LoadFile(schema_file, true,
+ &configurations_schema_binary_content);
+ if (!ok) return ok;
+
+ /* Load the binary schema */
+ ok = configurations_parser_.Deserialize(
+ (uint8_t*)configurations_schema_binary_content.c_str(),
+ configurations_schema_binary_content.length());
+ if (!ok) return ok;
+
+ /* Load the content from JSON */
+ std::string configurations_json_content;
+ ok = flatbuffers::LoadFile(content_file, false,
+ &configurations_json_content);
+ if (!ok) return ok;
+
+ /* Parse */
+ ok = configurations_parser_.Parse(configurations_json_content.c_str());
+ if (!ok) return ok;
+
+ /* Import from flatbuffers */
+ auto configurations_root = bluetooth::le_audio::GetAudioSetConfigurations(
+ configurations_parser_.builder_.GetBufferPointer());
+ if (!configurations_root) return false;
+
+ auto flat_configs = configurations_root->configurations();
+ if ((flat_configs == nullptr) || (flat_configs->size() == 0)) return false;
+
+ LOG_DEBUG(": Updating %d config entries.", flat_configs->size());
+ for (auto const& flat_cfg : *flat_configs) {
+ configurations_.insert(
+ {flat_cfg->name()->str(), AudioSetConfigurationFromFlat(flat_cfg)});
+ }
+
+ return true;
+ }
+
+ AudioSetConfigurations AudioSetConfigurationsFromFlatScenario(
+ const bluetooth::le_audio::AudioSetScenario* const flat_scenario) {
+ AudioSetConfigurations items;
+ if (!flat_scenario->configurations()) return items;
+
+ for (auto config_name : *flat_scenario->configurations()) {
+ if (configurations_.count(config_name->str()) == 0) continue;
+
+ auto& cfg = configurations_.at(config_name->str());
+ items.push_back(&cfg);
+ }
+
+ return items;
+ }
+
+ bool LoadScenariosFromFiles(const char* schema_file,
+ const char* content_file) {
+ flatbuffers::Parser scenarios_parser_;
+ std::string scenarios_schema_binary_content;
+ bool ok = flatbuffers::LoadFile(schema_file, true,
+ &scenarios_schema_binary_content);
+ if (!ok) return ok;
+
+ /* Load the binary schema */
+ ok = scenarios_parser_.Deserialize(
+ (uint8_t*)scenarios_schema_binary_content.c_str(),
+ scenarios_schema_binary_content.length());
+ if (!ok) return ok;
+
+ /* Load the content from JSON */
+ std::string scenarios_json_content;
+ ok = flatbuffers::LoadFile(content_file, false, &scenarios_json_content);
+ if (!ok) return ok;
+
+ /* Parse */
+ ok = scenarios_parser_.Parse(scenarios_json_content.c_str());
+ if (!ok) return ok;
+
+ /* Import from flatbuffers */
+ auto scenarios_root = bluetooth::le_audio::GetAudioSetScenarios(
+ scenarios_parser_.builder_.GetBufferPointer());
+ if (!scenarios_root) return false;
+
+ auto flat_scenarios = scenarios_root->scenarios();
+ if ((flat_scenarios == nullptr) || (flat_scenarios->size() == 0))
+ return false;
+
+ LOG_DEBUG(": Updating %d scenarios.", flat_scenarios->size());
+ for (auto const& scenario : *flat_scenarios) {
+ context_configurations_.insert_or_assign(
+ ScenarioToContextType(scenario->name()->c_str()),
+ AudioSetConfigurationsFromFlatScenario(scenario));
+ }
+
+ return true;
+ }
+
+ bool LoadContent(
+ std::vector<std::pair<const char* /*schema*/, const char* /*content*/>>
+ config_files,
+ std::vector<std::pair<const char* /*schema*/, const char* /*content*/>>
+ scenario_files) {
+ for (auto [schema, content] : config_files) {
+ if (!LoadConfigurationsFromFiles(schema, content)) return false;
+ }
+
+ for (auto [schema, content] : scenario_files) {
+ if (!LoadScenariosFromFiles(schema, content)) return false;
+ }
+ return true;
+ }
+
+ std::string ContextTypeToScenario(
+ ::le_audio::types::LeAudioContextType context_type) {
+ switch (context_type) {
+ case types::LeAudioContextType::MEDIA:
+ return "Media";
+ case types::LeAudioContextType::CONVERSATIONAL:
+ return "Conversational";
+ case types::LeAudioContextType::RINGTONE:
+ return "Ringtone";
+ default:
+ return "Default";
+ }
+ }
+
+ static ::le_audio::types::LeAudioContextType ScenarioToContextType(
+ std::string scenario) {
+ static const std::map<std::string, ::le_audio::types::LeAudioContextType>
+ scenarios = {
+ {"Media", types::LeAudioContextType::MEDIA},
+ {"Conversational", types::LeAudioContextType::CONVERSATIONAL},
+ {"Ringtone", types::LeAudioContextType::RINGTONE},
+ {"Default", types::LeAudioContextType::UNSPECIFIED},
+ };
+ return scenarios.count(scenario) ? scenarios.at(scenario)
+ : types::LeAudioContextType::RFU;
+ }
+};
+
+struct AudioSetConfigurationProvider::impl {
+ impl(const AudioSetConfigurationProvider& config_provider)
+ : config_provider_(config_provider) {}
+
+ void Initialize() {
+ ASSERT_LOG(!config_provider_impl_, " Config provider not available.");
+ config_provider_impl_ =
+ std::make_unique<AudioSetConfigurationProviderJson>();
+ }
+
+ void Cleanup() {
+ ASSERT_LOG(config_provider_impl_, " Config provider not available.");
+ config_provider_impl_.reset();
+ }
+
+ bool IsRunning() { return config_provider_impl_ ? true : false; }
+
+ const AudioSetConfigurationProvider& config_provider_;
+ std::unique_ptr<AudioSetConfigurationProviderJson> config_provider_impl_;
+};
+
+static std::unique_ptr<AudioSetConfigurationProvider> config_provider;
+
+AudioSetConfigurationProvider::AudioSetConfigurationProvider()
+ : pimpl_(std::make_unique<AudioSetConfigurationProvider::impl>(*this)) {}
+
+void AudioSetConfigurationProvider::Initialize() {
+ if (!config_provider)
+ config_provider = std::make_unique<AudioSetConfigurationProvider>();
+
+ if (!config_provider->pimpl_->IsRunning())
+ config_provider->pimpl_->Initialize();
+}
+
+void AudioSetConfigurationProvider::Cleanup() {
+ if (!config_provider) return;
+ if (config_provider->pimpl_->IsRunning()) config_provider->pimpl_->Cleanup();
+ config_provider.reset();
+}
+
+AudioSetConfigurationProvider* AudioSetConfigurationProvider::Get() {
+ return config_provider.get();
+}
+
+const set_configurations::AudioSetConfigurations*
+AudioSetConfigurationProvider::GetConfigurations(
+ ::le_audio::types::LeAudioContextType content_type) const {
+ if (CodecManager::GetInstance()->GetCodecLocation() ==
+ types::CodecLocation::ADSP) {
+ LOG_DEBUG("Get offload config for the context type: %d", (int)content_type);
+ const AudioSetConfigurations* offload_confs =
+ CodecManager::GetInstance()->GetOffloadCodecConfig(content_type);
+
+ if (offload_confs != nullptr && !(*offload_confs).empty()) {
+ return offload_confs;
+ }
+
+ // TODO: Need to have a mechanism to switch to software session if offload
+ // doesn't support.
+ }
+
+ LOG_DEBUG("Get software config for the context type: %d", (int)content_type);
+
+ if (pimpl_->IsRunning())
+ return pimpl_->config_provider_impl_->GetConfigurationsByContextType(
+ content_type);
+
+ return nullptr;
+}
+
+} // namespace le_audio
diff --git a/system/bta/le_audio/le_audio_types.cc b/system/bta/le_audio/le_audio_types.cc
index c74e8ecbc7..3c082fb338 100644
--- a/system/bta/le_audio/le_audio_types.cc
+++ b/system/bta/le_audio/le_audio_types.cc
@@ -36,6 +36,7 @@ using types::LeAudioContextType;
namespace set_configurations {
using set_configurations::CodecCapabilitySetting;
+using types::CodecLocation;
using types::kLeAudioCodingFormatLC3;
using types::kLeAudioDirectionSink;
using types::kLeAudioDirectionSource;
@@ -225,18 +226,6 @@ bool IsCodecCapabilitySettingSupported(
}
}
-const AudioSetConfigurations* get_confs_by_type(LeAudioContextType type) {
- switch (type) {
- case LeAudioContextType::MEDIA:
- return &audio_set_conf_media;
- case LeAudioContextType::CONVERSATIONAL:
- return &audio_set_conf_conversational;
- case LeAudioContextType::RINGTONE:
- return &audio_set_conf_ringtone;
- default:
- return &audio_set_conf_default;
- }
-}
uint32_t CodecCapabilitySetting::GetConfigSamplingFrequency() const {
switch (id.coding_format) {
case kLeAudioCodingFormatLC3:
diff --git a/system/bta/le_audio/le_audio_types.h b/system/bta/le_audio/le_audio_types.h
index 382683ad3c..5bd655c806 100644
--- a/system/bta/le_audio/le_audio_types.h
+++ b/system/bta/le_audio/le_audio_types.h
@@ -268,7 +268,9 @@ constexpr uint16_t kLeAudioVendorCodecIdUndefined = 0x00;
/* Metadata types from Assigned Numbers */
constexpr uint8_t kLeAudioMetadataTypePreferredAudioContext = 0x01;
constexpr uint8_t kLeAudioMetadataTypeStreamingAudioContext = 0x02;
-constexpr uint8_t kLeAudioMetadataTypeCcidList = 0x03;
+constexpr uint8_t kLeAudioMetadataTypeProgramInfo = 0x03;
+constexpr uint8_t kLeAudioMetadataTypeLanguage = 0x04;
+constexpr uint8_t kLeAudioMetadataTypeCcidList = 0x05;
constexpr uint8_t kLeAudioMetadataTypeLen = 1;
constexpr uint8_t kLeAudioMetadataLenLen = 1;
@@ -629,321 +631,6 @@ static constexpr uint32_t kChannelAllocationStereo =
codec_spec_conf::kLeAudioLocationFrontLeft |
codec_spec_conf::kLeAudioLocationFrontRight;
-/**
- * Supported audio codec capability settings
- *
- * The subset of capabilities defined in BAP_Validation_r13 Table 3.6.
- */
-constexpr CodecCapabilitySetting codec_lc3_16_1(uint8_t channel_count) {
- return CodecCapabilitySetting{
- .id = LeAudioCodecIdLc3,
- .config = types::LeAudioLc3Config({
- .sampling_frequency = codec_spec_conf::kLeAudioSamplingFreq16000Hz,
- .frame_duration = codec_spec_conf::kLeAudioCodecLC3FrameDur7500us,
- .octets_per_codec_frame = codec_spec_conf::kLeAudioCodecLC3FrameLen30,
- .channel_count = channel_count,
- .audio_channel_allocation = 0,
- })};
-}
-
-constexpr CodecCapabilitySetting codec_lc3_16_2(uint8_t channel_count) {
- return CodecCapabilitySetting{
- .id = LeAudioCodecIdLc3,
- .config = types::LeAudioLc3Config({
- .sampling_frequency = codec_spec_conf::kLeAudioSamplingFreq16000Hz,
- .frame_duration = codec_spec_conf::kLeAudioCodecLC3FrameDur10000us,
- .octets_per_codec_frame = codec_spec_conf::kLeAudioCodecLC3FrameLen40,
- .channel_count = channel_count,
- .audio_channel_allocation = 0,
- })};
-}
-
-constexpr CodecCapabilitySetting codec_lc3_48_4(uint8_t channel_count) {
- return CodecCapabilitySetting{
- .id = LeAudioCodecIdLc3,
- .config = types::LeAudioLc3Config({
- .sampling_frequency = codec_spec_conf::kLeAudioSamplingFreq48000Hz,
- .frame_duration = codec_spec_conf::kLeAudioCodecLC3FrameDur10000us,
- .octets_per_codec_frame =
- codec_spec_conf::kLeAudioCodecLC3FrameLen120,
- .channel_count = channel_count,
- .audio_channel_allocation = 0,
- })};
-}
-
-/*
- * AudioSetConfiguration defines the audio set configuration and codec settings
- * to to be used by le audio policy to match the required configuration with
- * audio server capabilities. The codec settings are defined with respect to
- * "Broadcast Source audio capability configuration support requirements"
- * defined in BAP d09r06
- */
-const AudioSetConfiguration kSingleDev_OneChanMonoSnk_16_2 = {
- .name = "kSingleDev_OneChanMonoSnk_16_2",
- .confs = {SetConfiguration(
- types::kLeAudioDirectionSink, 1, 1,
- codec_lc3_16_2(
- codec_spec_caps::kLeAudioCodecLC3ChannelCountSingleChannel))}};
-
-const AudioSetConfiguration kSingleDev_OneChanMonoSnk_16_1 = {
- .name = "kSingleDev_OneChanMonoSnk_16_1",
- .confs = {SetConfiguration(
- types::kLeAudioDirectionSink, 1, 1,
- codec_lc3_16_1(
- codec_spec_caps::kLeAudioCodecLC3ChannelCountSingleChannel))}};
-
-const AudioSetConfiguration kSingleDev_TwoChanStereoSnk_16_1 = {
- .name = "kSingleDev_TwoChanStereoSnk_16_1",
- .confs = {SetConfiguration(
- types::kLeAudioDirectionSink, 1, 1,
- codec_lc3_16_1(codec_spec_caps::kLeAudioCodecLC3ChannelCountTwoChannel),
- le_audio::types::LeAudioConfigurationStrategy::
- STEREO_ONE_CIS_PER_DEVICE)}};
-
-const AudioSetConfiguration kSingleDev_OneChanStereoSnk_16_1 = {
- .name = "kSingleDev_OneChanStereoSnk_16_1",
- .confs = {SetConfiguration(
- types::kLeAudioDirectionSink, 1, 2,
- codec_lc3_16_1(
- codec_spec_caps::kLeAudioCodecLC3ChannelCountSingleChannel),
- le_audio::types::LeAudioConfigurationStrategy::
- STEREO_TWO_CISES_PER_DEVICE)}};
-
-const AudioSetConfiguration kDualDev_OneChanStereoSnk_16_1 = {
- .name = "kDualDev_OneChanStereoSnk_16_1",
- .confs = {SetConfiguration(
- types::kLeAudioDirectionSink, 2, 2,
- codec_lc3_16_1(
- codec_spec_caps::kLeAudioCodecLC3ChannelCountSingleChannel))}};
-
-const AudioSetConfiguration kSingleDev_TwoChanStereoSnk_48_4 = {
- .name = "kSingleDev_TwoChanStereoSnk_48_4",
- .confs = {SetConfiguration(
- types::kLeAudioDirectionSink, 1, 1,
- codec_lc3_48_4(codec_spec_caps::kLeAudioCodecLC3ChannelCountTwoChannel),
- le_audio::types::LeAudioConfigurationStrategy::
- STEREO_ONE_CIS_PER_DEVICE)}};
-
-const AudioSetConfiguration kDualDev_OneChanStereoSnk_48_4 = {
- .name = "kDualDev_OneChanStereoSnk_48_4",
- .confs = {SetConfiguration(
- types::kLeAudioDirectionSink, 2, 2,
- codec_lc3_48_4(
- codec_spec_caps::kLeAudioCodecLC3ChannelCountSingleChannel))}};
-
-const AudioSetConfiguration kSingleDev_OneChanStereoSnk_48_4 = {
- .name = "kSingleDev_OneChanStereoSnk_48_4",
- .confs = {SetConfiguration(
- types::kLeAudioDirectionSink, 1, 2,
- codec_lc3_48_4(
- codec_spec_caps::kLeAudioCodecLC3ChannelCountSingleChannel),
- le_audio::types::LeAudioConfigurationStrategy::
- STEREO_TWO_CISES_PER_DEVICE)}};
-
-const AudioSetConfiguration kSingleDev_OneChanMonoSnk_48_4 = {
- .name = "kSingleDev_OneChanMonoSnk_48_4",
- .confs = {SetConfiguration(
- types::kLeAudioDirectionSink, 1, 1,
- codec_lc3_48_4(
- codec_spec_caps::kLeAudioCodecLC3ChannelCountSingleChannel))}};
-
-const AudioSetConfiguration kSingleDev_TwoChanStereoSnk_16_2 = {
- .name = "kSingleDev_TwoChanStereoSnk_16_2",
- .confs = {SetConfiguration(
- types::kLeAudioDirectionSink, 1, 1,
- codec_lc3_16_2(codec_spec_caps::kLeAudioCodecLC3ChannelCountTwoChannel),
- le_audio::types::LeAudioConfigurationStrategy::
- STEREO_ONE_CIS_PER_DEVICE)}};
-
-const AudioSetConfiguration kSingleDev_OneChanStereoSnk_16_2 = {
- .name = "kSingleDev_OneChanStereoSnk_16_2",
- .confs = {SetConfiguration(
- types::kLeAudioDirectionSink, 1, 2,
- codec_lc3_16_2(
- codec_spec_caps::kLeAudioCodecLC3ChannelCountSingleChannel),
- le_audio::types::LeAudioConfigurationStrategy::
- STEREO_TWO_CISES_PER_DEVICE)}};
-
-const AudioSetConfiguration kDualDev_OneChanStereoSnk_16_2 = {
- .name = "kDualDev_OneChanStereoSnk_16_2",
- .confs = {SetConfiguration(
- types::kLeAudioDirectionSink, 2, 2,
- codec_lc3_16_2(
- codec_spec_caps::kLeAudioCodecLC3ChannelCountSingleChannel))}};
-
-const AudioSetConfiguration kSingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1 = {
- .name = "kSingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1",
- .confs = {
- SetConfiguration(
- types::kLeAudioDirectionSink, 1, 1,
- codec_lc3_16_1(
- codec_spec_caps::kLeAudioCodecLC3ChannelCountSingleChannel)),
- SetConfiguration(
- types::kLeAudioDirectionSource, 1, 1,
- codec_lc3_16_1(
- codec_spec_caps::kLeAudioCodecLC3ChannelCountSingleChannel))}};
-
-const AudioSetConfiguration kSingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2 = {
- .name = "kSingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2",
- .confs = {
- SetConfiguration(
- types::kLeAudioDirectionSink, 1, 1,
- codec_lc3_16_2(
- codec_spec_caps::kLeAudioCodecLC3ChannelCountSingleChannel)),
- SetConfiguration(
- types::kLeAudioDirectionSource, 1, 1,
- codec_lc3_16_2(
- codec_spec_caps::kLeAudioCodecLC3ChannelCountSingleChannel))}};
-
-const AudioSetConfiguration kSingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2 = {
- .name = "kSingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2",
- .confs = {
- SetConfiguration(
- types::kLeAudioDirectionSink, 1, 1,
- codec_lc3_16_2(
- codec_spec_caps::kLeAudioCodecLC3ChannelCountTwoChannel),
- le_audio::types::LeAudioConfigurationStrategy::
- STEREO_ONE_CIS_PER_DEVICE),
- SetConfiguration(
- types::kLeAudioDirectionSource, 1, 1,
- codec_lc3_16_2(
- codec_spec_caps::kLeAudioCodecLC3ChannelCountSingleChannel))}};
-
-const AudioSetConfiguration
- kDualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2 = {
- .name = "kDualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2",
- .confs = {
- SetConfiguration(
- types::kLeAudioDirectionSink, 2, 4,
- codec_lc3_16_2(
- codec_spec_caps::kLeAudioCodecLC3ChannelCountSingleChannel),
- le_audio::types::LeAudioConfigurationStrategy::
- STEREO_TWO_CISES_PER_DEVICE),
- SetConfiguration(
- types::kLeAudioDirectionSource, 1, 1,
- codec_lc3_16_2(
- codec_spec_caps::
- kLeAudioCodecLC3ChannelCountSingleChannel))}};
-
-const AudioSetConfiguration kSingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2 = {
- .name = "kSingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
- .confs = {
- SetConfiguration(
- types::kLeAudioDirectionSink, 1, 2,
- codec_lc3_16_2(
- codec_spec_caps::kLeAudioCodecLC3ChannelCountSingleChannel),
- le_audio::types::LeAudioConfigurationStrategy::
- STEREO_TWO_CISES_PER_DEVICE),
- SetConfiguration(
- types::kLeAudioDirectionSource, 1, 1,
- codec_lc3_16_2(
- codec_spec_caps::kLeAudioCodecLC3ChannelCountSingleChannel))}};
-
-const AudioSetConfiguration kDualDev_OneChanStereoSnk_OneChanMonoSrc_16_2 = {
- .name = "kDualDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
- .confs = {
- SetConfiguration(
- types::kLeAudioDirectionSink, 2, 2,
- codec_lc3_16_2(
- codec_spec_caps::kLeAudioCodecLC3ChannelCountSingleChannel)),
- SetConfiguration(
- types::kLeAudioDirectionSource, 1, 1,
- codec_lc3_16_2(
- codec_spec_caps::kLeAudioCodecLC3ChannelCountSingleChannel))}};
-
-const AudioSetConfiguration kSingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1 = {
- .name = "kSingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1",
- .confs = {
- SetConfiguration(
- types::kLeAudioDirectionSink, 1, 1,
- codec_lc3_16_1(
- codec_spec_caps::kLeAudioCodecLC3ChannelCountTwoChannel),
- le_audio::types::LeAudioConfigurationStrategy::
- STEREO_ONE_CIS_PER_DEVICE),
- SetConfiguration(
- types::kLeAudioDirectionSource, 1, 1,
- codec_lc3_16_1(
- codec_spec_caps::kLeAudioCodecLC3ChannelCountSingleChannel))}};
-
-const AudioSetConfiguration kSingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1 = {
- .name = "kSingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
- .confs = {
- SetConfiguration(
- types::kLeAudioDirectionSink, 1, 2,
- codec_lc3_16_1(
- codec_spec_caps::kLeAudioCodecLC3ChannelCountSingleChannel),
- le_audio::types::LeAudioConfigurationStrategy::
- STEREO_TWO_CISES_PER_DEVICE),
- SetConfiguration(
- types::kLeAudioDirectionSource, 1, 1,
- codec_lc3_16_1(
- codec_spec_caps::kLeAudioCodecLC3ChannelCountSingleChannel))}};
-
-const AudioSetConfiguration kDualDev_OneChanStereoSnk_OneChanMonoSrc_16_1 = {
- .name = "kDualDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
- .confs = {
- SetConfiguration(
- types::kLeAudioDirectionSink, 2, 2,
- codec_lc3_16_1(
- codec_spec_caps::kLeAudioCodecLC3ChannelCountSingleChannel)),
- SetConfiguration(
- types::kLeAudioDirectionSource, 1, 1,
- codec_lc3_16_1(
- codec_spec_caps::kLeAudioCodecLC3ChannelCountSingleChannel))}};
-
-const AudioSetConfiguration
- kDualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1 = {
- .name = "kDualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1",
- .confs = {
- SetConfiguration(
- types::kLeAudioDirectionSink, 2, 4,
- codec_lc3_16_1(
- codec_spec_caps::kLeAudioCodecLC3ChannelCountSingleChannel),
- le_audio::types::LeAudioConfigurationStrategy::
- STEREO_TWO_CISES_PER_DEVICE),
- SetConfiguration(
- types::kLeAudioDirectionSource, 1, 1,
- codec_lc3_16_1(
- codec_spec_caps::
- kLeAudioCodecLC3ChannelCountSingleChannel))}};
-
-/* Defined audio scenario linked with context type, priority sorted */
-const AudioSetConfigurations audio_set_conf_ringtone = {
- &kDualDev_OneChanStereoSnk_16_2, &kDualDev_OneChanStereoSnk_16_1,
- &kSingleDev_OneChanStereoSnk_16_2, &kSingleDev_OneChanStereoSnk_16_1,
- &kSingleDev_TwoChanStereoSnk_16_2, &kSingleDev_TwoChanStereoSnk_16_1,
- &kSingleDev_OneChanMonoSnk_16_2, &kSingleDev_OneChanMonoSnk_16_1,
-};
-
-const AudioSetConfigurations audio_set_conf_conversational = {
- &kDualDev_OneChanStereoSnk_OneChanMonoSrc_16_2,
- &kDualDev_OneChanStereoSnk_OneChanMonoSrc_16_1,
- &kDualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2,
- &kDualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1,
- &kSingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2,
- &kSingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1,
- &kSingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2,
- &kSingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1,
- &kSingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2,
- &kSingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1,
-};
-
-const AudioSetConfigurations audio_set_conf_media = {
- &kDualDev_OneChanStereoSnk_48_4, &kDualDev_OneChanStereoSnk_16_2,
- &kDualDev_OneChanStereoSnk_16_1, &kSingleDev_OneChanStereoSnk_48_4,
- &kSingleDev_OneChanStereoSnk_16_2, &kSingleDev_OneChanStereoSnk_16_1,
- &kSingleDev_TwoChanStereoSnk_48_4, &kSingleDev_TwoChanStereoSnk_16_2,
- &kSingleDev_TwoChanStereoSnk_16_1, &kSingleDev_OneChanMonoSnk_48_4,
- &kSingleDev_OneChanMonoSnk_16_2, &kSingleDev_OneChanMonoSnk_16_1,
-};
-
-const AudioSetConfigurations audio_set_conf_default = {
- &kDualDev_OneChanStereoSnk_16_2,
- &kSingleDev_OneChanStereoSnk_16_2,
- &kSingleDev_TwoChanStereoSnk_16_2,
- &kSingleDev_OneChanMonoSnk_16_2,
-};
-
/* Declarations */
bool check_if_may_cover_scenario(
const AudioSetConfigurations* audio_set_configurations, uint8_t group_size);
@@ -952,7 +639,6 @@ bool check_if_may_cover_scenario(
bool IsCodecCapabilitySettingSupported(
const types::acs_ac_record& pac_record,
const CodecCapabilitySetting& codec_capability_setting);
-const AudioSetConfigurations* get_confs_by_type(types::LeAudioContextType type);
uint8_t get_num_of_devices_in_configuration(
const AudioSetConfiguration* audio_set_configuration);
} // namespace set_configurations
diff --git a/system/bta/le_audio/mock_codec_manager.cc b/system/bta/le_audio/mock_codec_manager.cc
index 15c952a323..eaacf4bd51 100644
--- a/system/bta/le_audio/mock_codec_manager.cc
+++ b/system/bta/le_audio/mock_codec_manager.cc
@@ -38,16 +38,27 @@ types::CodecLocation CodecManager::GetCodecLocation() const {
}
void CodecManager::UpdateActiveSourceAudioConfig(
- const stream_configuration& stream_conf, uint16_t delay) {
- if (pimpl_) return pimpl_->UpdateActiveSourceAudioConfig(stream_conf, delay);
+ const stream_configuration& stream_conf, uint16_t delay_ms) {
+ if (pimpl_)
+ return pimpl_->UpdateActiveSourceAudioConfig(stream_conf, delay_ms);
}
void CodecManager::UpdateActiveSinkAudioConfig(
- const stream_configuration& stream_conf, uint16_t delay) {
- if (pimpl_) return pimpl_->UpdateActiveSinkAudioConfig(stream_conf, delay);
+ const stream_configuration& stream_conf, uint16_t delay_ms) {
+ if (pimpl_) return pimpl_->UpdateActiveSinkAudioConfig(stream_conf, delay_ms);
}
-void CodecManager::Start() {
+const set_configurations::AudioSetConfigurations*
+CodecManager::GetOffloadCodecConfig(types::LeAudioContextType ctx_type) {
+ if (!pimpl_) return nullptr;
+ return pimpl_->GetOffloadCodecConfig(ctx_type);
+}
+
+void CodecManager::Start(
+ const std::vector<bluetooth::le_audio::btle_audio_codec_config_t>&
+ offloading_preference,
+ const std::vector<set_configurations::AudioSetConfiguration>&
+ adsp_capabilities) {
// It is needed here as CodecManager which is a singleton creates it, but in
// this mock we want to destroy and recreate the mock on each test case.
if (!pimpl_) {
diff --git a/system/bta/le_audio/mock_codec_manager.h b/system/bta/le_audio/mock_codec_manager.h
index ef020a6a86..d191a5fd04 100644
--- a/system/bta/le_audio/mock_codec_manager.h
+++ b/system/bta/le_audio/mock_codec_manager.h
@@ -25,6 +25,9 @@ class MockCodecManager {
static MockCodecManager* GetInstance();
MockCodecManager() = default;
+ MockCodecManager(const MockCodecManager&) = delete;
+ MockCodecManager& operator=(const MockCodecManager&) = delete;
+
virtual ~MockCodecManager() = default;
MOCK_METHOD((le_audio::types::CodecLocation), GetCodecLocation, (), (const));
@@ -34,10 +37,10 @@ class MockCodecManager {
MOCK_METHOD((void), UpdateActiveSinkAudioConfig,
(const le_audio::stream_configuration& stream_conf,
uint16_t delay));
+ MOCK_METHOD((le_audio::set_configurations::AudioSetConfigurations*),
+ GetOffloadCodecConfig,
+ (le_audio::types::LeAudioContextType ctx_type), (const));
MOCK_METHOD((void), Start, ());
MOCK_METHOD((void), Stop, ());
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockCodecManager);
};
diff --git a/system/bta/le_audio/mock_iso_manager.h b/system/bta/le_audio/mock_iso_manager.h
index e4a10abccb..8db3ade2a5 100644
--- a/system/bta/le_audio/mock_iso_manager.h
+++ b/system/bta/le_audio/mock_iso_manager.h
@@ -26,6 +26,9 @@ struct MockIsoManager {
static MockIsoManager* GetInstance();
MockIsoManager() = default;
+ MockIsoManager(const MockIsoManager&) = delete;
+ MockIsoManager& operator=(const MockIsoManager&) = delete;
+
virtual ~MockIsoManager() = default;
MOCK_METHOD((void), RegisterCigCallbacks,
@@ -68,7 +71,4 @@ struct MockIsoManager {
MOCK_METHOD((void), Start, ());
MOCK_METHOD((void), Stop, ());
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockIsoManager);
};
diff --git a/system/bta/le_audio/state_machine.cc b/system/bta/le_audio/state_machine.cc
index 3eb38ae644..e71af9516c 100644
--- a/system/bta/le_audio/state_machine.cc
+++ b/system/bta/le_audio/state_machine.cc
@@ -211,7 +211,8 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
void StopStream(LeAudioDeviceGroup* group) override {
if (group->IsReleasing()) {
- LOG(INFO) << __func__ << ", group already in releasing process";
+ LOG(INFO) << __func__ << ", group: " << group->group_id_
+ << " already in releasing process";
return;
}
@@ -499,6 +500,13 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
return;
}
+ /* If group is in Idle there is nothing to do here */
+ if ((group->GetState() == AseState::BTA_LE_AUDIO_ASE_STATE_IDLE) &&
+ (group->GetTargetState() == AseState::BTA_LE_AUDIO_ASE_STATE_IDLE)) {
+ LOG(INFO) << __func__ << " group: " << group->group_id_ << " is in IDLE";
+ return;
+ }
+
auto* stream_conf = &group->stream_conf;
if (!stream_conf->sink_streams.empty() ||
!stream_conf->source_streams.empty()) {
@@ -544,13 +552,8 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
}
/* Group is not connected and all the CISes are down.
- * If group is in Idle there is nothing to do here */
- if (group->GetState() == AseState::BTA_LE_AUDIO_ASE_STATE_IDLE) {
- LOG(INFO) << __func__ << " group: " << group->group_id_ << " is in IDLE";
- return;
- }
-
- /* Clean states and destroy HCI group */
+ * Clean states and destroy HCI group
+ */
group->SetState(AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
group->SetTargetState(AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
if (alarm_is_scheduled(watchdog_)) alarm_cancel(watchdog_);
@@ -594,7 +597,9 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
}
if (group->GetTargetState() != AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
- LOG(ERROR) << __func__ << ", Unintended CIS establishement event came";
+ LOG(ERROR) << __func__
+ << ", Unintended CIS establishement event came for group id:"
+ << group->group_id_;
StopStream(group);
return;
}
diff --git a/system/bta/le_audio/state_machine_test.cc b/system/bta/le_audio/state_machine_test.cc
index c11fab8f30..aa700730e5 100644
--- a/system/bta/le_audio/state_machine_test.cc
+++ b/system/bta/le_audio/state_machine_test.cc
@@ -27,6 +27,7 @@
#include "btm_api_mock.h"
#include "client_parser.h"
#include "fake_osi.h"
+#include "le_audio_set_configuration_provider.h"
#include "mock_codec_manager.h"
#include "mock_controller.h"
#include "mock_iso_manager.h"
@@ -136,14 +137,16 @@ class MockLeAudioGroupStateMachineCallbacks
: public LeAudioGroupStateMachine::Callbacks {
public:
MockLeAudioGroupStateMachineCallbacks() = default;
+ MockLeAudioGroupStateMachineCallbacks(
+ const MockLeAudioGroupStateMachineCallbacks&) = delete;
+ MockLeAudioGroupStateMachineCallbacks& operator=(
+ const MockLeAudioGroupStateMachineCallbacks&) = delete;
+
~MockLeAudioGroupStateMachineCallbacks() override = default;
MOCK_METHOD((void), StatusReportCb,
(int group_id, bluetooth::le_audio::GroupStreamStatus status),
(override));
MOCK_METHOD((void), OnStateTransitionTimeout, (int group_id), (override));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockLeAudioGroupStateMachineCallbacks);
};
class StateMachineTest : public Test {
@@ -156,6 +159,7 @@ class StateMachineTest : public Test {
gatt::SetMockBtaGattQueue(&gatt_queue);
ase_id_last_assigned = types::ase::kAseIdInvalid;
+ ::le_audio::AudioSetConfigurationProvider::Initialize();
LeAudioGroupStateMachine::Initialize(&mock_callbacks_);
// Support 2M Phy
@@ -384,7 +388,11 @@ class StateMachineTest : public Test {
void ConfigCodecManagerMock() {
codec_manager_ = le_audio::CodecManager::GetInstance();
ASSERT_NE(codec_manager_, nullptr);
- codec_manager_->Start();
+ std::vector<bluetooth::le_audio::btle_audio_codec_config_t>
+ mock_offloading_preference(0);
+ std::vector<set_configurations::AudioSetConfiguration>
+ mock_adsp_capabilities(0);
+ codec_manager_->Start(mock_offloading_preference, mock_adsp_capabilities);
mock_codec_manager_ = MockCodecManager::GetInstance();
ASSERT_NE(mock_codec_manager_, nullptr);
ON_CALL(*mock_codec_manager_, GetCodecLocation())
@@ -408,6 +416,7 @@ class StateMachineTest : public Test {
le_audio_devices_.clear();
cached_codec_configuration_map_.clear();
LeAudioGroupStateMachine::Cleanup();
+ ::le_audio::AudioSetConfigurationProvider::Cleanup();
}
std::shared_ptr<LeAudioDevice> PrepareConnectedDevice(uint8_t id,
@@ -2116,6 +2125,31 @@ TEST_F(StateMachineTest, testAseAutonomousRelease) {
}
}
+TEST_F(StateMachineTest, testStateTransitionTimeoutOnIdleState) {
+ const auto context_type = kContextTypeRingtone;
+ const int leaudio_group_id = 4;
+
+ // Prepare fake connected device group
+ auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type);
+
+ auto* leAudioDevice = group->GetFirstDevice();
+ EXPECT_CALL(gatt_queue,
+ WriteCharacteristic(1, leAudioDevice->ctp_hdls_.val_hdl, _,
+ GATT_WRITE_NO_RSP, _, _))
+ .Times(1);
+
+ // Start the configuration and stream Media content
+ ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
+ group, static_cast<types::LeAudioContextType>(context_type)));
+
+ // Disconnect device
+ LeAudioGroupStateMachine::Get()->ProcessHciNotifAclDisconnected(
+ group, leAudioDevice);
+
+ // Make sure timeout is cleared
+ ASSERT_TRUE(fake_osi_alarm_set_on_mloop_.cb == nullptr);
+}
+
TEST_F(StateMachineTest, testStateTransitionTimeout) {
const auto context_type = kContextTypeRingtone;
const int leaudio_group_id = 4;
diff --git a/system/bta/vc/devices.h b/system/bta/vc/devices.h
index 71dc6c9e00..f2ce3014ba 100644
--- a/system/bta/vc/devices.h
+++ b/system/bta/vc/devices.h
@@ -17,6 +17,7 @@
#pragma once
+#include <algorithm>
#include <cstdint>
#include <unordered_set>
#include <vector>
diff --git a/system/bta/vc/types.h b/system/bta/vc/types.h
index 4461d65c92..a8a4b252c8 100644
--- a/system/bta/vc/types.h
+++ b/system/bta/vc/types.h
@@ -50,6 +50,7 @@ struct VolumeOperation {
int group_id_;
bool started_;
+ bool is_autonomous_;
uint8_t opcode_;
std::vector<uint8_t> arguments_;
@@ -57,11 +58,12 @@ struct VolumeOperation {
std::vector<RawAddress> devices_;
alarm_t* operation_timeout_;
- VolumeOperation(int operation_id, int group_id, uint8_t opcode,
+ VolumeOperation(int operation_id, int group_id, bool is_autonomous, uint8_t opcode,
std::vector<uint8_t> arguments,
std::vector<RawAddress> devices)
: operation_id_(operation_id),
group_id_(group_id),
+ is_autonomous_(is_autonomous),
opcode_(opcode),
arguments_(arguments),
devices_(devices) {
diff --git a/system/bta/vc/vc.cc b/system/bta/vc/vc.cc
index 08f61e8774..23a20bf8c8 100644
--- a/system/bta/vc/vc.cc
+++ b/system/bta/vc/vc.cc
@@ -285,7 +285,7 @@ class VolumeControlImpl : public VolumeControl {
if (!csis_api) {
DLOG(INFO) << __func__ << " Csis is not available";
callbacks_->OnVolumeStateChanged(device->address, device->volume,
- device->mute);
+ device->mute, true);
return;
}
@@ -294,7 +294,7 @@ class VolumeControlImpl : public VolumeControl {
if (group_id == bluetooth::groups::kGroupUnknown) {
DLOG(INFO) << __func__ << " No group for device " << device->address;
callbacks_->OnVolumeStateChanged(device->address, device->volume,
- device->mute);
+ device->mute, true);
return;
}
@@ -310,7 +310,7 @@ class VolumeControlImpl : public VolumeControl {
if (is_volume_change) {
std::vector<uint8_t> arg({device->volume});
- PrepareVolumeControlOperation(devices, group_id,
+ PrepareVolumeControlOperation(devices, group_id, true,
kControlPointOpcodeSetAbsoluteVolume, arg);
}
@@ -318,7 +318,7 @@ class VolumeControlImpl : public VolumeControl {
std::vector<uint8_t> arg;
uint8_t opcode =
device->mute ? kControlPointOpcodeMute : kControlPointOpcodeUnmute;
- PrepareVolumeControlOperation(devices, group_id, opcode, arg);
+ PrepareVolumeControlOperation(devices, group_id, true, opcode, arg);
}
StartQueueOperation();
@@ -354,7 +354,7 @@ class VolumeControlImpl : public VolumeControl {
/* This is just a read, send single notification */
if (!is_notification) {
callbacks_->OnVolumeStateChanged(device->address, device->volume,
- device->mute);
+ device->mute, false);
return;
}
@@ -384,12 +384,15 @@ class VolumeControlImpl : public VolumeControl {
return;
}
- if (op->IsGroupOperation())
+ if (op->IsGroupOperation()) {
callbacks_->OnGroupVolumeStateChanged(op->group_id_, device->volume,
- device->mute);
- else
+ device->mute, op->is_autonomous_);
+ } else {
+ /* op->is_autonomous_ will always be false,
+ since we only make it true for group operations */
callbacks_->OnVolumeStateChanged(device->address, device->volume,
- device->mute);
+ device->mute, false);
+ }
ongoing_operations_.erase(op);
StartQueueOperation();
@@ -591,14 +594,16 @@ class VolumeControlImpl : public VolumeControl {
}
void PrepareVolumeControlOperation(std::vector<RawAddress>& devices,
- int group_id, uint8_t opcode,
+ int group_id, bool is_autonomous,
+ uint8_t opcode,
std::vector<uint8_t>& arguments) {
DLOG(INFO) << __func__ << " num of devices: " << devices.size()
- << " group_id: " << group_id << " opcode: " << +opcode
+ << " group_id: " << group_id << " is_autonomous: " << is_autonomous
+ << " opcode: " << +opcode
<< " arg size: " << arguments.size();
- ongoing_operations_.emplace_back(latest_operation_id_++, group_id, opcode,
- arguments, devices);
+ ongoing_operations_.emplace_back(latest_operation_id_++, group_id, is_autonomous,
+ opcode, arguments, devices);
}
void SetVolume(std::variant<RawAddress, int> addr_or_group_id,
@@ -613,7 +618,7 @@ class VolumeControlImpl : public VolumeControl {
std::vector<RawAddress> devices = {
std::get<RawAddress>(addr_or_group_id)};
- PrepareVolumeControlOperation(devices, bluetooth::groups::kGroupUnknown,
+ PrepareVolumeControlOperation(devices, bluetooth::groups::kGroupUnknown, false,
opcode, arg);
} else {
/* Handle group change */
@@ -641,7 +646,7 @@ class VolumeControlImpl : public VolumeControl {
return;
}
- PrepareVolumeControlOperation(devices, group_id, opcode, arg);
+ PrepareVolumeControlOperation(devices, group_id, false, opcode, arg);
}
StartQueueOperation();
@@ -681,7 +686,7 @@ class VolumeControlImpl : public VolumeControl {
// once profile connected we can notify current states
callbacks_->OnVolumeStateChanged(device->address, device->volume,
- device->mute);
+ device->mute, false);
device->EnqueueRemainingRequests(gatt_if_, chrc_read_callback_static,
OnGattWriteCccStatic);
diff --git a/system/bta/vc/vc_test.cc b/system/bta/vc/vc_test.cc
index 41d4f20117..0e52d4a1be 100644
--- a/system/bta/vc/vc_test.cc
+++ b/system/bta/vc/vc_test.cc
@@ -66,18 +66,19 @@ RawAddress GetTestAddress(int index) {
class MockVolumeControlCallbacks : public VolumeControlCallbacks {
public:
MockVolumeControlCallbacks() = default;
+ MockVolumeControlCallbacks(const MockVolumeControlCallbacks&) = delete;
+ MockVolumeControlCallbacks& operator=(const MockVolumeControlCallbacks&) =
+ delete;
+
~MockVolumeControlCallbacks() override = default;
MOCK_METHOD((void), OnConnectionState,
(ConnectionState state, const RawAddress& address), (override));
MOCK_METHOD((void), OnVolumeStateChanged,
- (const RawAddress& address, uint8_t volume, bool mute),
+ (const RawAddress& address, uint8_t volume, bool mute, bool isAutonomous),
(override));
MOCK_METHOD((void), OnGroupVolumeStateChanged,
- (int group_id, uint8_t volume, bool mute), (override));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockVolumeControlCallbacks);
+ (int group_id, uint8_t volume, bool mute, bool isAutonomous), (override));
};
class VolumeControlTest : public ::testing::Test {
@@ -560,7 +561,7 @@ TEST_F(VolumeControlTest, test_subscribe_vcs_volume_state) {
TEST_F(VolumeControlTest, test_read_vcs_volume_state) {
const RawAddress test_address = GetTestAddress(0);
- EXPECT_CALL(*callbacks, OnVolumeStateChanged(test_address, _, _));
+ EXPECT_CALL(*callbacks, OnVolumeStateChanged(test_address, _, _, false));
std::vector<uint16_t> handles({0x0021});
TestReadCharacteristic(test_address, 1, handles);
}
@@ -605,12 +606,12 @@ class VolumeControlCallbackTest : public VolumeControlTest {
TEST_F(VolumeControlCallbackTest, test_volume_state_changed) {
std::vector<uint8_t> value({0x03, 0x01, 0x02});
- EXPECT_CALL(*callbacks, OnVolumeStateChanged(test_address, 0x03, true));
+ EXPECT_CALL(*callbacks, OnVolumeStateChanged(test_address, 0x03, true, true));
GetNotificationEvent(0x0021, value);
}
TEST_F(VolumeControlCallbackTest, test_volume_state_changed_malformed) {
- EXPECT_CALL(*callbacks, OnVolumeStateChanged(test_address, _, _)).Times(0);
+ EXPECT_CALL(*callbacks, OnVolumeStateChanged(test_address, _, _, _)).Times(0);
std::vector<uint8_t> too_short({0x03, 0x01});
GetNotificationEvent(0x0021, too_short);
std::vector<uint8_t> too_long({0x03, 0x01, 0x02, 0x03});
@@ -726,7 +727,7 @@ TEST_F(VolumeControlCsis, test_set_volume) {
VolumeControl::Get()->SetVolume(group_id, 10);
/* Now inject notification and make sure callback is sent up to Java layer */
- EXPECT_CALL(*callbacks, OnGroupVolumeStateChanged(group_id, 0x03, true));
+ EXPECT_CALL(*callbacks, OnGroupVolumeStateChanged(group_id, 0x03, true, false));
std::vector<uint8_t> value({0x03, 0x01, 0x02});
GetNotificationEvent(conn_id_1, test_address_1, 0x0021, value);
@@ -735,7 +736,7 @@ TEST_F(VolumeControlCsis, test_set_volume) {
TEST_F(VolumeControlCsis, autonomus_test_set_volume) {
/* Now inject notification and make sure callback is sent up to Java layer */
- EXPECT_CALL(*callbacks, OnGroupVolumeStateChanged(group_id, 0x03, false));
+ EXPECT_CALL(*callbacks, OnGroupVolumeStateChanged(group_id, 0x03, false, true));
std::vector<uint8_t> value({0x03, 0x00, 0x02});
GetNotificationEvent(conn_id_1, test_address_1, 0x0021, value);
diff --git a/system/btcore/fuzzer/btcore_property_fuzzer.cpp b/system/btcore/fuzzer/btcore_property_fuzzer.cpp
index 0bb0c019c1..c6bfd445ba 100644
--- a/system/btcore/fuzzer/btcore_property_fuzzer.cpp
+++ b/system/btcore/fuzzer/btcore_property_fuzzer.cpp
@@ -58,8 +58,8 @@ void BTCorePropertyFuzzer::process(const uint8_t* data, size_t size) {
property_free(property);
uint32_t timeout = mFdp->ConsumeIntegral<uint32_t>();
- property = property_new_discovery_timeout(timeout);
- (void)property_as_discovery_timeout(property);
+ property = property_new_discoverable_timeout(timeout);
+ (void)property_as_discoverable_timeout(property);
property_free(property);
std::string name = mFdp->ConsumeRandomLengthString(kRandomStringLength);
diff --git a/system/btcore/include/property.h b/system/btcore/include/property.h
index 73d4d41e7c..2ef94e73a0 100644
--- a/system/btcore/include/property.h
+++ b/system/btcore/include/property.h
@@ -46,7 +46,7 @@ bool property_equals(const bt_property_t* p1, const bt_property_t* p2);
bt_property_t* property_new_addr(const RawAddress* addr);
bt_property_t* property_new_device_class(const bt_device_class_t* dc);
bt_property_t* property_new_device_type(bt_device_type_t device_type);
-bt_property_t* property_new_discovery_timeout(const uint32_t timeout);
+bt_property_t* property_new_discoverable_timeout(const uint32_t timeout);
bt_property_t* property_new_name(const char* name);
bt_property_t* property_new_rssi(const int8_t rssi);
bt_property_t* property_new_scan_mode(bt_scan_mode_t scan_mode);
@@ -62,7 +62,7 @@ void property_free_array(bt_property_t* properties, size_t count);
bool property_is_addr(const bt_property_t* property);
bool property_is_device_class(const bt_property_t* property);
bool property_is_device_type(const bt_property_t* property);
-bool property_is_discovery_timeout(const bt_property_t* property);
+bool property_is_discoverable_timeout(const bt_property_t* property);
bool property_is_name(const bt_property_t* property);
bool property_is_rssi(const bt_property_t* property);
bool property_is_scan_mode(const bt_property_t* property);
@@ -74,7 +74,7 @@ const RawAddress* property_as_addr(const bt_property_t* property);
const bt_device_class_t* property_as_device_class(
const bt_property_t* property);
bt_device_type_t property_as_device_type(const bt_property_t* property);
-uint32_t property_as_discovery_timeout(const bt_property_t* property);
+uint32_t property_as_discoverable_timeout(const bt_property_t* property);
const bt_bdname_t* property_as_name(const bt_property_t* property);
int8_t property_as_rssi(const bt_property_t* property);
bt_scan_mode_t property_as_scan_mode(const bt_property_t* property);
diff --git a/system/btcore/src/property.cc b/system/btcore/src/property.cc
index 7b5a3033ff..94679e9961 100644
--- a/system/btcore/src/property.cc
+++ b/system/btcore/src/property.cc
@@ -98,9 +98,9 @@ bt_property_t* property_new_device_type(bt_device_type_t type) {
BT_PROPERTY_TYPE_OF_DEVICE);
}
-bt_property_t* property_new_discovery_timeout(const uint32_t timeout) {
+bt_property_t* property_new_discoverable_timeout(const uint32_t timeout) {
return property_new_((void*)&timeout, sizeof(uint32_t),
- BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT);
+ BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT);
}
bt_property_t* property_new_name(const char* name) {
@@ -151,9 +151,9 @@ bool property_is_device_type(const bt_property_t* property) {
return property->type == BT_PROPERTY_TYPE_OF_DEVICE;
}
-bool property_is_discovery_timeout(const bt_property_t* property) {
+bool property_is_discoverable_timeout(const bt_property_t* property) {
CHECK(property != NULL);
- return property->type == BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT;
+ return property->type == BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT;
}
bool property_is_name(const bt_property_t* property) {
@@ -193,8 +193,8 @@ bt_device_type_t property_as_device_type(const bt_property_t* property) {
return *(const bt_device_type_t*)property->val;
}
-uint32_t property_as_discovery_timeout(const bt_property_t* property) {
- CHECK(property_is_discovery_timeout(property));
+uint32_t property_as_discoverable_timeout(const bt_property_t* property) {
+ CHECK(property_is_discoverable_timeout(property));
return *(const uint32_t*)property->val;
}
diff --git a/system/btcore/test/property_test.cc b/system/btcore/test/property_test.cc
index ee8ed22666..4e24e0d0a1 100644
--- a/system/btcore/test/property_test.cc
+++ b/system/btcore/test/property_test.cc
@@ -81,13 +81,13 @@ TEST_F(PropertyTest, device_type) {
TEST_F(PropertyTest, discovery_timeout) {
uint32_t timeout0 = 12345;
- bt_property_t* property = property_new_discovery_timeout(timeout0);
+ bt_property_t* property = property_new_discoverable_timeout(timeout0);
EXPECT_EQ(timeout0, *(uint32_t*)property->val);
- EXPECT_EQ(BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT, property->type);
+ EXPECT_EQ(BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT, property->type);
EXPECT_EQ((int)sizeof(uint32_t), property->len);
- uint32_t timeout1 = property_as_discovery_timeout(property);
+ uint32_t timeout1 = property_as_discoverable_timeout(property);
EXPECT_EQ(timeout0, timeout1);
property_free(property);
diff --git a/system/btif/Android.bp b/system/btif/Android.bp
index 92f14ea6e5..c31250d800 100644
--- a/system/btif/Android.bp
+++ b/system/btif/Android.bp
@@ -164,7 +164,6 @@ cc_defaults {
"android.hardware.bluetooth.a2dp@1.0",
"android.hardware.bluetooth.audio@2.0",
"android.hardware.bluetooth.audio@2.1",
- "android.hardware.bluetooth.audio@2.2",
"libcrypto",
"libflatbuffers-cpp",
"libhidlbase",
@@ -228,7 +227,6 @@ cc_test {
"android.hardware.bluetooth.a2dp@1.0",
"android.hardware.bluetooth.audio@2.0",
"android.hardware.bluetooth.audio@2.1",
- "android.hardware.bluetooth.audio@2.2",
"android.system.suspend.control-V1-ndk",
"libbinder_ndk",
"libfmq",
@@ -247,7 +245,6 @@ cc_test {
"libbt-utils",
"libFraunhoferAAC",
"libg722codec",
- "liblc3codec",
"liblc3",
"libbtdevice",
"libbt-hci",
@@ -470,7 +467,6 @@ cc_test {
"android.hardware.bluetooth.a2dp@1.0",
"android.hardware.bluetooth.audio@2.0",
"android.hardware.bluetooth.audio@2.1",
- "android.hardware.bluetooth.audio@2.2",
"libcrypto",
"libcutils",
"libflatbuffers-cpp",
diff --git a/system/btif/include/btif_common.h b/system/btif/include/btif_common.h
index 3782b506b1..434950988f 100644
--- a/system/btif/include/btif_common.h
+++ b/system/btif/include/btif_common.h
@@ -232,7 +232,6 @@ void invoke_link_quality_report_cb(
int retransmission_count, int packets_not_receive_count,
int negative_acknowledgement_count);
-void invoke_switch_buffer_size_cb(RawAddress remote_addr,
- bool is_low_latency_buffer_size);
+void invoke_switch_buffer_size_cb(bool is_low_latency_buffer_size);
#endif /* BTIF_COMMON_H */
diff --git a/system/btif/include/btif_dm.h b/system/btif/include/btif_dm.h
index dbf047670c..b3f70217a3 100644
--- a/system/btif/include/btif_dm.h
+++ b/system/btif/include/btif_dm.h
@@ -67,6 +67,8 @@ bool btif_dm_proc_rmt_oob(const RawAddress& bd_addr, Octet16* p_c,
void btif_dm_generate_local_oob_data(tBT_TRANSPORT transport);
#endif /* BTIF_DM_OOB_TEST */
+void btif_dm_clear_event_filter();
+
/*callout for reading SMP properties from Text file*/
bool btif_dm_get_smp_config(tBTE_APPL_CFG* p_cfg);
diff --git a/system/btif/src/bluetooth.cc b/system/btif/src/bluetooth.cc
index b44d593e29..e76c617fed 100644
--- a/system/btif/src/bluetooth.cc
+++ b/system/btif/src/bluetooth.cc
@@ -262,7 +262,7 @@ static int set_adapter_property(const bt_property_t* property) {
switch (property->type) {
case BT_PROPERTY_BDNAME:
case BT_PROPERTY_ADAPTER_SCAN_MODE:
- case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
+ case BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT:
case BT_PROPERTY_CLASS_OF_DEVICE:
case BT_PROPERTY_LOCAL_IO_CAPS:
case BT_PROPERTY_LOCAL_IO_CAPS_BLE:
@@ -412,6 +412,14 @@ static int read_energy_info() {
return BT_STATUS_SUCCESS;
}
+static int clear_event_filter() {
+ LOG_VERBOSE("%s", __func__);
+ if (!interface_ready()) return BT_STATUS_NOT_READY;
+
+ do_in_main_thread(FROM_HERE, base::BindOnce(btif_dm_clear_event_filter));
+ return BT_STATUS_SUCCESS;
+}
+
static void dump(int fd, const char** arguments) {
btif_debug_conn_dump(fd);
btif_debug_bond_event_dump(fd);
@@ -620,7 +628,8 @@ static int set_dynamic_audio_buffer_size(int codec, int size) {
static bool allow_low_latency_audio(bool allowed, const RawAddress& address) {
LOG_INFO("%s %s", __func__, allowed ? "true" : "false");
- return bluetooth::audio::a2dp::set_audio_low_latency_mode_allowed(allowed);
+ bluetooth::audio::a2dp::set_audio_low_latency_mode_allowed(allowed);
+ return true;
}
EXPORT_SYMBOL bt_interface_t bluetoothInterface = {
@@ -662,7 +671,8 @@ EXPORT_SYMBOL bt_interface_t bluetoothInterface = {
get_metric_id,
set_dynamic_audio_buffer_size,
generate_local_oob_data,
- allow_low_latency_audio};
+ allow_low_latency_audio,
+ clear_event_filter};
// callback reporting helpers
@@ -924,14 +934,13 @@ void invoke_link_quality_report_cb(
packets_not_receive_count, negative_acknowledgement_count));
}
-void invoke_switch_buffer_size_cb(RawAddress remote_addr,
- bool is_low_latency_buffer_size) {
+void invoke_switch_buffer_size_cb(bool is_low_latency_buffer_size) {
do_in_jni_thread(
FROM_HERE,
base::BindOnce(
- [](RawAddress remote_addr, bool is_low_latency_buffer_size) {
- HAL_CBACK(bt_hal_cbacks, switch_buffer_size_cb, &remote_addr,
+ [](bool is_low_latency_buffer_size) {
+ HAL_CBACK(bt_hal_cbacks, switch_buffer_size_cb,
is_low_latency_buffer_size);
},
- remote_addr, is_low_latency_buffer_size));
+ is_low_latency_buffer_size));
}
diff --git a/system/btif/src/btif_av.cc b/system/btif/src/btif_av.cc
index b2fc783c32..e67722156f 100644
--- a/system/btif/src/btif_av.cc
+++ b/system/btif/src/btif_av.cc
@@ -2320,6 +2320,15 @@ bool BtifAvStateMachine::StateClosing::ProcessEvent(uint32_t event,
btif_a2dp_on_offload_started(peer_.PeerAddress(), BTA_AV_FAIL);
break;
+ case BTIF_AV_CONNECT_REQ_EVT:
+ BTIF_TRACE_WARNING("%s: Peer %s : Ignore %s in StateClosing",
+ __PRETTY_FUNCTION__,
+ peer_.PeerAddress().ToString().c_str(),
+ BtifAvEvent::EventName(event).c_str());
+ btif_queue_advance();
+ peer_.StateMachine().TransitionTo(BtifAvStateMachine::kStateIdle);
+ break;
+
default:
BTIF_TRACE_WARNING("%s: Peer %s : Unhandled event=%s",
__PRETTY_FUNCTION__,
diff --git a/system/btif/src/btif_core.cc b/system/btif/src/btif_core.cc
index 87dd06bae7..bdcf66ee25 100644
--- a/system/btif/src/btif_core.cc
+++ b/system/btif/src/btif_core.cc
@@ -439,7 +439,7 @@ static bt_status_t btif_in_get_adapter_properties(void) {
/* DISC_TIMEOUT */
BTIF_STORAGE_FILL_PROPERTY(&properties[num_props],
- BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT,
+ BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT,
sizeof(disc_timeout), &disc_timeout);
btif_storage_get_adapter_property(&properties[num_props]);
num_props++;
@@ -721,7 +721,7 @@ void btif_set_adapter_property(bt_property_t* property) {
btif_core_storage_adapter_write(property);
}
} break;
- case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT: {
+ case BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT: {
/* Nothing to do beside store the value in NV. Java
will change the SCAN_MODE property after setting timeout,
if required */
diff --git a/system/btif/src/btif_debug_btsnoop.cc b/system/btif/src/btif_debug_btsnoop.cc
index 1c13590170..11e783d2b9 100644
--- a/system/btif/src/btif_debug_btsnoop.cc
+++ b/system/btif/src/btif_debug_btsnoop.cc
@@ -23,214 +23,15 @@
#include <zlib.h>
#include "internal_include/bt_target.h"
+#include "osi/include/properties.h"
#include "osi/include/ringbuffer.h"
#define REDUCE_HCI_TYPE_TO_SIGNIFICANT_BITS(type) ((type) >> 8)
// Total btsnoop memory log buffer size
#ifndef BTSNOOP_MEM_BUFFER_SIZE
-static const size_t BTSNOOP_MEM_BUFFER_SIZE = (256 * 1024);
#endif
-static std::mutex buffer_mutex;
-static ringbuffer_t* buffer = NULL;
-static uint64_t last_timestamp_ms = 0;
-
-static size_t btsnoop_calculate_packet_length(uint16_t type,
- const uint8_t* data,
- size_t length);
-
-static void btsnoop_cb(const uint16_t type, const uint8_t* data,
- const size_t length, const uint64_t timestamp_us) {
- btsnooz_header_t header;
-
- size_t included_length = btsnoop_calculate_packet_length(type, data, length);
- if (included_length == 0) return;
-
- std::lock_guard<std::mutex> lock(buffer_mutex);
-
- // Make room in the ring buffer
-
- while (ringbuffer_available(buffer) <
- (included_length + sizeof(btsnooz_header_t))) {
- ringbuffer_pop(buffer, (uint8_t*)&header, sizeof(btsnooz_header_t));
- ringbuffer_delete(buffer, header.length - 1);
- }
-
- // Insert data
- header.type = REDUCE_HCI_TYPE_TO_SIGNIFICANT_BITS(type);
- header.length = included_length + 1; // +1 for type byte
- header.packet_length = length + 1; // +1 for type byte.
- header.delta_time_ms =
- last_timestamp_ms ? timestamp_us - last_timestamp_ms : 0;
- last_timestamp_ms = timestamp_us;
-
- ringbuffer_insert(buffer, (uint8_t*)&header, sizeof(btsnooz_header_t));
- ringbuffer_insert(buffer, data, included_length);
-}
-
-static size_t btsnoop_calculate_packet_length(uint16_t type,
- const uint8_t* data,
- size_t length) {
- static const size_t HCI_ACL_HEADER_SIZE = 4;
- static const size_t L2CAP_HEADER_SIZE = 4;
- static const size_t L2CAP_CID_OFFSET = (HCI_ACL_HEADER_SIZE + 2);
- static const uint16_t L2CAP_SIGNALING_CID = 0x0001;
-
- // Maximum amount of ACL data to log.
- // Enough for an RFCOMM frame up to the frame check;
- // not enough for a HID report or audio data.
- static const size_t MAX_HCI_ACL_LEN = 14;
-
- // Calculate packet length to be included
-
- switch (type) {
- case BT_EVT_TO_LM_HCI_CMD:
- return length;
-
- case BT_EVT_TO_BTU_HCI_EVT:
- return length;
-
- case BT_EVT_TO_LM_HCI_ACL:
- case BT_EVT_TO_BTU_HCI_ACL: {
- size_t len_hci_acl = HCI_ACL_HEADER_SIZE + L2CAP_HEADER_SIZE;
- // Check if we have enough data for an L2CAP header
- if (length > len_hci_acl) {
- uint16_t l2cap_cid =
- data[L2CAP_CID_OFFSET] | (data[L2CAP_CID_OFFSET + 1] << 8);
- if (l2cap_cid == L2CAP_SIGNALING_CID) {
- // For the signaling CID, take the full packet.
- // That way, the PSM setup is captured, allowing decoding of PSMs down
- // the road.
- return length;
- } else {
- // Otherwise, return as much as we reasonably can
- len_hci_acl = MAX_HCI_ACL_LEN;
- }
- }
- return len_hci_acl < length ? len_hci_acl : length;
- }
-
- case BT_EVT_TO_LM_HCI_ISO:
- case BT_EVT_TO_BTU_HCI_ISO:
- return length;
-
- case BT_EVT_TO_LM_HCI_SCO:
- case BT_EVT_TO_BTU_HCI_SCO:
- // We're not logging SCO packets at this time since they are not currently
- // used.
- FALLTHROUGH_INTENDED; /* FALLTHROUGH */
- default:
- return 0;
- }
-}
-
-void btif_debug_btsnoop_init(void) {
- if (buffer == NULL) buffer = ringbuffer_init(BTSNOOP_MEM_BUFFER_SIZE);
- btsnoop_mem_set_callback(btsnoop_cb);
-}
-
#ifndef OS_ANDROID
-void btif_debug_btsnoop_dump(int fd) {}
#else
-
-// Block size for copying buffers (for compression/encoding etc.)
-static constexpr size_t BLOCK_SIZE = 16384;
-
-static bool btsnoop_compress(ringbuffer_t* rb_dst, ringbuffer_t* rb_src) {
- CHECK(rb_dst != NULL);
- CHECK(rb_src != NULL);
-
- z_stream zs;
- zs.zalloc = Z_NULL;
- zs.zfree = Z_NULL;
- zs.opaque = Z_NULL;
-
- if (deflateInit(&zs, Z_DEFAULT_COMPRESSION) != Z_OK) return false;
-
- bool rc = true;
- uint8_t block_src[BLOCK_SIZE];
- uint8_t block_dst[BLOCK_SIZE];
-
- const size_t num_blocks =
- (ringbuffer_size(rb_src) + BLOCK_SIZE - 1) / BLOCK_SIZE;
- for (size_t i = 0; i < num_blocks; ++i) {
- zs.avail_in =
- ringbuffer_peek(rb_src, i * BLOCK_SIZE, block_src, BLOCK_SIZE);
- zs.next_in = block_src;
-
- do {
- zs.avail_out = BLOCK_SIZE;
- zs.next_out = block_dst;
-
- int err = deflate(&zs, (i == num_blocks - 1) ? Z_FINISH : Z_NO_FLUSH);
- if (err == Z_STREAM_ERROR) {
- rc = false;
- break;
- }
-
- const size_t length = BLOCK_SIZE - zs.avail_out;
- ringbuffer_insert(rb_dst, block_dst, length);
- } while (zs.avail_out == 0);
- }
-
- deflateEnd(&zs);
- return rc;
-}
-
-void btif_debug_btsnoop_dump(int fd) {
- ringbuffer_t* ringbuffer = ringbuffer_init(BTSNOOP_MEM_BUFFER_SIZE);
- if (ringbuffer == NULL) {
- dprintf(fd, "%s Unable to allocate memory for compression", __func__);
- return;
- }
-
- // Prepend preamble
-
- btsnooz_preamble_t preamble;
- preamble.version = BTSNOOZ_CURRENT_VERSION;
- preamble.last_timestamp_ms = last_timestamp_ms;
- ringbuffer_insert(ringbuffer, (uint8_t*)&preamble,
- sizeof(btsnooz_preamble_t));
-
- // Compress data
-
- uint8_t b64_in[3] = {0};
- char b64_out[5] = {0};
-
- size_t line_length = 0;
-
- bool rc;
- {
- std::lock_guard<std::mutex> lock(buffer_mutex);
- dprintf(fd, "--- BEGIN:BTSNOOP_LOG_SUMMARY (%zu bytes in) ---\n",
- ringbuffer_size(buffer));
- rc = btsnoop_compress(ringbuffer, buffer);
- }
-
- if (!rc) {
- dprintf(fd, "%s Log compression failed", __func__);
- goto error;
- }
-
- // Base64 encode & output
-
- while (ringbuffer_size(ringbuffer) > 0) {
- size_t read = ringbuffer_pop(ringbuffer, b64_in, 3);
- // Maximum line length in bugreport (should be multiple of 4 for base64
- // output)
- constexpr uint8_t MAX_LINE_LENGTH = 128;
- if (line_length >= MAX_LINE_LENGTH) {
- dprintf(fd, "\n");
- line_length = 0;
- }
- line_length += b64_ntop(b64_in, read, b64_out, 5);
- dprintf(fd, "%s", b64_out);
- }
-
- dprintf(fd, "\n--- END:BTSNOOP_LOG_SUMMARY ---\n");
-
-error:
- ringbuffer_free(ringbuffer);
-}
#endif
diff --git a/system/btif/src/btif_dm.cc b/system/btif/src/btif_dm.cc
index 989f7399a2..28abdabf5e 100644
--- a/system/btif/src/btif_dm.cc
+++ b/system/btif/src/btif_dm.cc
@@ -95,9 +95,8 @@ const Uuid UUID_VC = Uuid::FromString("1844");
const Uuid UUID_CSIS = Uuid::FromString("1846");
const Uuid UUID_LE_AUDIO = Uuid::FromString("184E");
const Uuid UUID_LE_MIDI = Uuid::FromString("03B80E5A-EDE8-4B33-A751-6CE34EC4C700");
-/* FIXME: Not known yet, using a placeholder instead. */
-const Uuid UUID_HAS = Uuid::FromString("EEEEEEEE-EEEE-EEEE-EEEE-EEEEEEEEEEEE");
-const bool enable_address_consolidate = false; // TODO remove
+const Uuid UUID_HAS = Uuid::FromString("1854");
+const bool enable_address_consolidate = true; // TODO remove
#define COD_MASK 0x07FF
@@ -2180,7 +2179,7 @@ bt_status_t btif_dm_get_adapter_property(bt_property_t* prop) {
prop->len = sizeof(bt_scan_mode_t);
} break;
- case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT: {
+ case BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT: {
uint32_t* tmt = (uint32_t*)prop->val;
*tmt = 120; /* default to 120s, if not found in NV */
prop->len = sizeof(uint32_t);
@@ -3206,3 +3205,8 @@ bool btif_get_address_type(const RawAddress& bda, tBLE_ADDR_TYPE* p_addr_type) {
AddressTypeText(*p_addr_type).c_str());
return true;
}
+
+void btif_dm_clear_event_filter() {
+ LOG_VERBOSE("%s: called", __func__);
+ bta_dm_clear_event_filter();
+}
diff --git a/system/btif/src/btif_hh.cc b/system/btif/src/btif_hh.cc
index ae4ee067cf..bff20a0686 100644
--- a/system/btif/src/btif_hh.cc
+++ b/system/btif/src/btif_hh.cc
@@ -905,6 +905,12 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) {
case BTA_HH_GET_PROTO_EVT:
p_dev = btif_hh_find_connected_dev_by_handle(p_data->hs_data.handle);
+ if (p_dev == NULL) {
+ BTIF_TRACE_WARNING(
+ "BTA_HH_GET_PROTO_EVT: Error, cannot find device with handle %d",
+ p_data->hs_data.handle);
+ return;
+ }
BTIF_TRACE_WARNING(
"BTA_HH_GET_PROTO_EVT: status = %d, handle = %d, proto = [%d], %s",
p_data->hs_data.status, p_data->hs_data.handle,
@@ -941,9 +947,11 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) {
p_data->hs_data.handle, p_data->hs_data.status,
p_data->hs_data.rsp_data.idle_rate);
p_dev = btif_hh_find_connected_dev_by_handle(p_data->hs_data.handle);
- HAL_CBACK(bt_hh_callbacks, idle_time_cb, (RawAddress*)&(p_dev->bd_addr),
- (bthh_status_t)p_data->hs_data.status,
- p_data->hs_data.rsp_data.idle_rate);
+ if (p_dev) {
+ HAL_CBACK(bt_hh_callbacks, idle_time_cb, (RawAddress*)&(p_dev->bd_addr),
+ (bthh_status_t)p_data->hs_data.status,
+ p_data->hs_data.rsp_data.idle_rate);
+ }
break;
case BTA_HH_SET_IDLE_EVT:
diff --git a/system/btif/src/btif_le_audio.cc b/system/btif/src/btif_le_audio.cc
index 4660a2ccc5..acb7ed703f 100644
--- a/system/btif/src/btif_le_audio.cc
+++ b/system/btif/src/btif_le_audio.cc
@@ -79,18 +79,27 @@ class LeAudioClientInterfaceImpl : public LeAudioClientInterface,
LOG_INFO("supported codec: %s", codec.ToString().c_str());
}
+ LeAudioClient::InitializeAudioSetConfigurationProvider();
do_in_main_thread(
FROM_HERE, Bind(&LeAudioClient::Initialize, this,
jni_thread_wrapper(
FROM_HERE, Bind(&btif_storage_load_bonded_leaudio)),
base::Bind([]() -> bool {
return LeAudioHalVerifier::SupportsLeAudio();
- })));
+ }),
+ offloading_preference));
}
void Cleanup(void) override {
DVLOG(2) << __func__;
- do_in_main_thread(FROM_HERE, Bind(&LeAudioClient::Cleanup));
+ do_in_main_thread(
+ FROM_HERE,
+ Bind(
+ &LeAudioClient::Cleanup,
+ jni_thread_wrapper(
+ FROM_HERE,
+ Bind(
+ &LeAudioClient::CleanupAudioSetConfigurationProvider))));
}
void RemoveDevice(const RawAddress& address) override {
diff --git a/system/btif/src/btif_le_audio_broadcaster.cc b/system/btif/src/btif_le_audio_broadcaster.cc
index be55da65a2..57d14f93fc 100644
--- a/system/btif/src/btif_le_audio_broadcaster.cc
+++ b/system/btif/src/btif_le_audio_broadcaster.cc
@@ -21,6 +21,7 @@
#include <hardware/bt_le_audio.h>
#include "audio_hal_interface/hal_version_manager.h"
+#include "bta_le_audio_api.h"
#include "bta_le_audio_broadcaster_api.h"
#include "btif_common.h"
#include "stack/include/btu.h"
@@ -46,8 +47,7 @@ class LeAudioBroadcasterInterfaceImpl : public LeAudioBroadcasterInterface,
do_in_main_thread(
FROM_HERE,
Bind(&LeAudioBroadcaster::Initialize, this, base::Bind([]() -> bool {
- return bluetooth::audio::HalVersionManager::GetHalVersion() ==
- bluetooth::audio::BluetoothAudioHalVersion::VERSION_2_1;
+ return LeAudioHalVerifier::SupportsLeAudioBroadcast();
})));
}
diff --git a/system/btif/src/btif_sock_thread.cc b/system/btif/src/btif_sock_thread.cc
index 88f40e75cc..6744d3d10c 100644
--- a/system/btif/src/btif_sock_thread.cc
+++ b/system/btif/src/btif_sock_thread.cc
@@ -448,6 +448,10 @@ static void process_data_sock(int h, struct pollfd* pfds, int count) {
for (i = 1; i < ts[h].poll_count; i++) {
if (pfds[i].revents) {
int ps_i = ts[h].psi[i];
+ if (ts[h].ps[ps_i].pfd.fd == -1) {
+ LOG_INFO("Socket has been removed from poll set");
+ continue;
+ }
asrt(pfds[i].fd == ts[h].ps[ps_i].pfd.fd);
uint32_t user_id = ts[h].ps[ps_i].user_id;
int type = ts[h].ps[ps_i].type;
diff --git a/system/btif/src/btif_storage.cc b/system/btif/src/btif_storage.cc
index 7838f9e6d6..1f130d726f 100644
--- a/system/btif/src/btif_storage.cc
+++ b/system/btif/src/btif_storage.cc
@@ -248,7 +248,7 @@ static int prop2cfg(const RawAddress* remote_bd_addr, bt_property_t* prop) {
btif_config_set_int("Adapter", BTIF_STORAGE_KEY_LOCAL_IO_CAPS_BLE,
*(int*)prop->val);
break;
- case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
+ case BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT:
btif_config_set_int("Adapter", BTIF_STORAGE_KEY_ADAPTER_DISC_TIMEOUT,
*(int*)prop->val);
break;
@@ -358,7 +358,7 @@ static int cfg2prop(const RawAddress* remote_bd_addr, bt_property_t* prop) {
(int*)prop->val);
break;
- case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
+ case BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT:
if (prop->len >= (int)sizeof(int))
ret = btif_config_get_int(
"Adapter", BTIF_STORAGE_KEY_ADAPTER_DISC_TIMEOUT, (int*)prop->val);
@@ -1040,9 +1040,9 @@ bt_status_t btif_storage_load_bonded_devices(void) {
num_props++;
/* DISC_TIMEOUT */
- BTIF_STORAGE_GET_ADAPTER_PROP(status, BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT,
- &disc_timeout, sizeof(disc_timeout),
- adapter_props[num_props]);
+ BTIF_STORAGE_GET_ADAPTER_PROP(
+ status, BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT, &disc_timeout,
+ sizeof(disc_timeout), adapter_props[num_props]);
num_props++;
/* BONDED_DEVICES */
diff --git a/system/btif/src/btif_util.cc b/system/btif/src/btif_util.cc
index 86307bc881..bcd0ef96fc 100644
--- a/system/btif/src/btif_util.cc
+++ b/system/btif/src/btif_util.cc
@@ -129,7 +129,7 @@ const char* dump_property_type(bt_property_type_t type) {
CASE_RETURN_STR(BT_PROPERTY_CLASS_OF_DEVICE)
CASE_RETURN_STR(BT_PROPERTY_TYPE_OF_DEVICE)
CASE_RETURN_STR(BT_PROPERTY_REMOTE_RSSI)
- CASE_RETURN_STR(BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT)
+ CASE_RETURN_STR(BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT)
CASE_RETURN_STR(BT_PROPERTY_ADAPTER_BONDED_DEVICES)
CASE_RETURN_STR(BT_PROPERTY_ADAPTER_SCAN_MODE)
CASE_RETURN_STR(BT_PROPERTY_REMOTE_FRIENDLY_NAME)
diff --git a/system/btif/src/btif_vc.cc b/system/btif/src/btif_vc.cc
index 66374e215e..61ecb20172 100644
--- a/system/btif/src/btif_vc.cc
+++ b/system/btif/src/btif_vc.cc
@@ -55,21 +55,21 @@ class VolumeControlInterfaceImpl : public VolumeControlInterface,
}
void OnVolumeStateChanged(const RawAddress& address, uint8_t volume,
- bool mute) override {
- DVLOG(2) << __func__ << " address: " << address << "volume: " << volume
- << "mute: " << mute;
+ bool mute, bool isAutonomous) override {
+ DVLOG(2) << __func__ << " address: " << address << " volume: " << volume
+ << " mute: " << mute << " isAutonomous: " << isAutonomous;
do_in_jni_thread(FROM_HERE,
Bind(&VolumeControlCallbacks::OnVolumeStateChanged,
- Unretained(callbacks_), address, volume, mute));
+ Unretained(callbacks_), address, volume, mute, isAutonomous));
}
void OnGroupVolumeStateChanged(int group_id, uint8_t volume,
- bool mute) override {
- DVLOG(2) << __func__ << "group_id: " << group_id << "volume: " << volume
- << "mute: " << mute;
+ bool mute, bool isAutonomous) override {
+ DVLOG(2) << __func__ << " group_id: " << group_id << " volume: " << volume
+ << " mute: " << mute << " isAutonomous: " << isAutonomous;
do_in_jni_thread(FROM_HERE,
Bind(&VolumeControlCallbacks::OnGroupVolumeStateChanged,
- Unretained(callbacks_), group_id, volume, mute));
+ Unretained(callbacks_), group_id, volume, mute, isAutonomous));
}
void Connect(const RawAddress& address) override {
diff --git a/system/btif/src/stack_manager.cc b/system/btif/src/stack_manager.cc
index fe730e7d6e..d7cc4931b6 100644
--- a/system/btif/src/stack_manager.cc
+++ b/system/btif/src/stack_manager.cc
@@ -191,16 +191,13 @@ static void clean_up_stack() {
static bool get_stack_is_running() { return stack_is_running; }
// Internal functions
-
extern const module_t bt_utils_module;
extern const module_t bte_logmsg_module;
extern const module_t btif_config_module;
-extern const module_t btsnoop_module;
extern const module_t bt_utils_module;
extern const module_t gd_controller_module;
extern const module_t gd_idle_module;
extern const module_t gd_shim_module;
-extern const module_t hci_module;
extern const module_t interop_module;
extern const module_t osi_module;
extern const module_t stack_config_module;
diff --git a/system/btif/test/btif_core_test.cc b/system/btif/test/btif_core_test.cc
index 50fd519e98..28d9cccdb7 100644
--- a/system/btif/test/btif_core_test.cc
+++ b/system/btif/test/btif_core_test.cc
@@ -79,6 +79,7 @@ void energy_info_callback(bt_activity_energy_info* energy_info,
bt_uid_traffic_t* uid_data) {}
void generate_local_oob_data_callback(tBT_TRANSPORT transport,
bt_oob_data_t oob_data) {}
+void switch_buffer_size_callback(bool is_low_latency_buffer_size) {}
#undef TESTCB
bt_callbacks_t callbacks = {
@@ -99,6 +100,7 @@ bt_callbacks_t callbacks = {
.energy_info_cb = energy_info_callback,
.link_quality_report_cb = link_quality_report_callback,
.generate_local_oob_data_cb = generate_local_oob_data_callback,
+ .switch_buffer_size_cb = switch_buffer_size_callback,
};
} // namespace
diff --git a/system/build/Android.bp b/system/build/Android.bp
index f0f2a3b7c8..70c509957f 100644
--- a/system/build/Android.bp
+++ b/system/build/Android.bp
@@ -120,8 +120,6 @@ fluoride_defaults {
"android.hardware.bluetooth@1.0",
"android.hardware.bluetooth@1.1",
"libcutils",
- "libgrpc++",
- "libgrpc_wrap",
"libhidlbase",
"libstatslog_bt",
"libutils",
diff --git a/system/build/dpkg/libchrome-822064/debian/README.Debian b/system/build/dpkg/libchrome-822064/debian/README.Debian
deleted file mode 100644
index 773bbf318e..0000000000
--- a/system/build/dpkg/libchrome-822064/debian/README.Debian
+++ /dev/null
@@ -1 +0,0 @@
-libchrome for Debian
diff --git a/system/build/dpkg/libchrome-822064/debian/changelog b/system/build/dpkg/libchrome-822064/debian/changelog
deleted file mode 100644
index 113a5e756a..0000000000
--- a/system/build/dpkg/libchrome-822064/debian/changelog
+++ /dev/null
@@ -1,5 +0,0 @@
-libchrome (822064-1) buster; urgency=low
-
- * Initial release.
-
- -- Sonny Sasaka <sonnysasaka@chromium.org> Fri, 30 Apr 2021 19:41:40 +0000
diff --git a/system/build/dpkg/libchrome-822064/debian/compat b/system/build/dpkg/libchrome-822064/debian/compat
deleted file mode 100644
index f599e28b8a..0000000000
--- a/system/build/dpkg/libchrome-822064/debian/compat
+++ /dev/null
@@ -1 +0,0 @@
-10
diff --git a/system/build/dpkg/libchrome-822064/debian/control b/system/build/dpkg/libchrome-822064/debian/control
deleted file mode 100644
index b11c23fbc2..0000000000
--- a/system/build/dpkg/libchrome-822064/debian/control
+++ /dev/null
@@ -1,28 +0,0 @@
-Source: libchrome
-Section: libs
-Priority: optional
-Maintainer: Sonny Sasaka <sonnysasaka@chromium.org>
-Standards-Version: 4.1.4
-Homepage: https://chromium.googlesource.com/aosp/platform/external/libchrome/
-Build-Depends:
- debhelper (>=11~),
- clang,
- python3,
- pkg-config,
- ninja-build,
- libglib2.0-dev,
- libevent-dev,
- libnss3-dev,
- libdbus-1-dev,
- libprotobuf-dev,
- googletest,
- libre2-dev,
- libdouble-conversion-dev,
- libssl-dev,
- libabsl-dev
-
-Package: libchrome
-Architecture: any
-Multi-Arch: foreign
-Depends: ${misc:Depends}, ${shlibs:Depends}
-Description: Chromium's base library
diff --git a/system/build/dpkg/libchrome-822064/debian/install_headers.sh b/system/build/dpkg/libchrome-822064/debian/install_headers.sh
deleted file mode 100755
index 7157b1499d..0000000000
--- a/system/build/dpkg/libchrome-822064/debian/install_headers.sh
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/bin/bash
-
-destdir="$1"
-
-header_dirs=(
- base
- base/allocator
- base/containers
- base/debug
- base/files
- base/hash
- base/i18n
- base/json
- base/memory
- base/message_loop
- base/metrics
- base/numerics
- base/posix
- base/process
- base/ranges
- base/strings
- base/synchronization
- base/system
- base/task
- base/task/common
- base/task/sequence_manager
- base/task/thread_pool
- base/test
- base/third_party/icu
- base/third_party/nspr
- base/third_party/valgrind
- base/threading
- base/time
- base/timer
- base/trace_event
- base/trace_event/common
- build
- components/policy
- components/policy/core/common
- testing/gmock/include/gmock
- testing/gtest/include/gtest
- dbus
- third_party/abseil-cpp/absl/types
- )
-
-# Install header files.
-for d in "${header_dirs[@]}" ; do
- mkdir -p "${destdir}/usr/include/libchrome/${d}"
- cp libchrome/"${d}"/*.h "${destdir}/usr/include/libchrome/${d}"
-done
diff --git a/system/build/dpkg/libchrome-822064/debian/libchrome.install b/system/build/dpkg/libchrome-822064/debian/libchrome.install
deleted file mode 100644
index 9d381c1e2b..0000000000
--- a/system/build/dpkg/libchrome-822064/debian/libchrome.install
+++ /dev/null
@@ -1,4 +0,0 @@
-out/Release/lib/libbase*.so /usr/lib
-out/Release/libbase*.a /usr/lib
-out/Release/obj/libchrome/libchrome*.pc /usr/lib/pkgconfig
-usr/include /usr
diff --git a/system/build/dpkg/libchrome-822064/debian/patches/0001-Add-missing-includes.patch b/system/build/dpkg/libchrome-822064/debian/patches/0001-Add-missing-includes.patch
deleted file mode 100644
index a2f2b4b9ad..0000000000
--- a/system/build/dpkg/libchrome-822064/debian/patches/0001-Add-missing-includes.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 50a4636886c958717213856132fcbb57c3b8ea2a Mon Sep 17 00:00:00 2001
-From: Sonny Sasaka <sonnysasaka@chromium.org>
-Date: Fri, 19 Mar 2021 16:18:07 -0700
-Subject: [PATCH] Add missing includes
-
----
- base/hash/md5.cc | 1 +
- crypto/p224_spake.cc | 1 +
- 2 files changed, 2 insertions(+)
-
-diff --git a/libchrome/base/hash/md5.cc b/libchrome/base/hash/md5.cc
-index bdb9990a9..ef8954eaf 100644
---- a/libchrome/base/hash/md5.cc
-+++ b/libchrome/base/hash/md5.cc
-@@ -24,6 +24,7 @@
- #include "base/hash/md5.h"
-
- #include <stddef.h>
-+#include <string.h>
-
- namespace {
-
-diff --git a/libchrome/crypto/p224_spake.cc b/libchrome/crypto/p224_spake.cc
-index 157410537..de0af5466 100644
---- a/libchrome/crypto/p224_spake.cc
-+++ b/libchrome/crypto/p224_spake.cc
-@@ -8,6 +8,7 @@
- #include <crypto/p224_spake.h>
-
- #include <algorithm>
-+#include <string.h>
-
- #include <base/logging.h>
- #include <crypto/p224.h>
---
-2.20.1
-
diff --git a/system/build/dpkg/libchrome-822064/debian/patches/0001-rebase_path-for-write_args.patch b/system/build/dpkg/libchrome-822064/debian/patches/0001-rebase_path-for-write_args.patch
deleted file mode 100644
index 9b359c0e8d..0000000000
--- a/system/build/dpkg/libchrome-822064/debian/patches/0001-rebase_path-for-write_args.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 6875449497baf026fb8228668930a715ffcc7082 Mon Sep 17 00:00:00 2001
-From: Sonny Sasaka <sonnysasaka@chromium.org>
-Date: Fri, 19 Mar 2021 16:56:59 -0700
-Subject: [PATCH] rebase_path for write_args
-
----
- BUILD.gn | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/libchrome/BUILD.gn b/libchrome/BUILD.gn
-index a846d8f52..66ac10a55 100644
---- a/libchrome/BUILD.gn
-+++ b/libchrome/BUILD.gn
-@@ -556,7 +556,7 @@ action("base") {
-
- script = "//common-mk/write_args.py"
- outputs = [ "${root_out_dir}/lib/lib${target_name}.so" ]
-- args = [ "--output" ] + outputs + [ "--" ] + [
-+ args = [ "--output" ] + rebase_path(outputs) + [ "--" ] + [
- "GROUP",
- "(",
- "AS_NEEDED",
-@@ -618,7 +618,7 @@ action("base-test") {
-
- script = "//common-mk/write_args.py"
- outputs = [ "${root_out_dir}/lib${target_name}.a" ]
-- args = [ "--output" ] + outputs + [ "--" ] + [
-+ args = [ "--output" ] + rebase_path(outputs) + [ "--" ] + [
- "GROUP",
- "(",
- "AS_NEEDED",
---
-2.20.1
-
diff --git a/system/build/dpkg/libchrome-822064/debian/patches/series b/system/build/dpkg/libchrome-822064/debian/patches/series
deleted file mode 100644
index 9128588280..0000000000
--- a/system/build/dpkg/libchrome-822064/debian/patches/series
+++ /dev/null
@@ -1,3 +0,0 @@
-0001-Add-missing-includes.patch
-0001-rebase_path-for-write_args.patch
-0001-Remove-absl-from-pkgconfig.patch
diff --git a/system/build/dpkg/libchrome-822064/debian/rules b/system/build/dpkg/libchrome-822064/debian/rules
deleted file mode 100755
index 60b6792048..0000000000
--- a/system/build/dpkg/libchrome-822064/debian/rules
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/make -f
-
-# gn args
-defines =
-defines += pkg_config=\"pkg-config\"
-defines += libbase_ver=\"822064\"
-defines += platform2_root=\"$(shell pwd)/\"
-defines += platform_subdir=\"libchrome\"
-defines += cxx=\"clang++\"
-defines += cc=\"clang\"
-defines += ar=\"ar\"
-defines += external_cxxflags=[\"-DNDEBUG\", \"-I/usr/src/googletest/googletest/include\", \"-I/usr/src/googletest/googlemock/include\", \"-Wno-unknown-warning-option\", \"-Wno-unused-command-line-argument\"]
-defines += external_ldflags=[\"-latomic\", \"-labsl_base\", \"-labsl_bad_variant_access\"]
-defines += enable_werror=false
-defines += libdir=\"/usr/lib\"
-defines += use={mojo=false asan=false coverage=false crypto=true dbus=true fuzzer=false timers=true cros_host=false profiling=false tcmalloc=false}
-
-# handle parallel build options
-njobs=1
-ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
-njobs=$(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
-endif
-
-%:
- dh $@ --parallel
-
-override_dh_auto_build-arch:
- gn gen out/Release --args="$(defines)"
- ninja -j$(njobs) -C out/Release
-
-override_dh_auto_clean:
- rm -rf out
- find . -name \*.pyc -execdir rm -f {} \;
- dh_auto_clean
-
-override_dh_auto_install-arch:
- dh_auto_install
- debian/install_headers.sh debian/tmp
diff --git a/system/build/dpkg/libchrome-822064/gen-src-pkg.sh b/system/build/dpkg/libchrome-822064/gen-src-pkg.sh
deleted file mode 100755
index cbb5dce54a..0000000000
--- a/system/build/dpkg/libchrome-822064/gen-src-pkg.sh
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/bin/bash
-# Generates Debian source and binary packages of libchrome.
-
-if [ -z "$1" ]; then
- echo "Usage: gen-src-pkg.sh <output-dir>"
- exit 1
-fi
-
-outdir="$1"
-pkgdir=libchrome-822064
-origtar=libchrome_822064.orig.tar.gz
-scriptdir="$( cd "$( dirname "$0" )" && pwd )"
-branch=release-R91-13904.B
-
-tmpdir=$(mktemp -d)
-echo Generating source package in "${tmpdir}".
-
-# Download platform2 source.
-cd "${tmpdir}"
-git clone --branch "${branch}" https://chromium.googlesource.com/chromiumos/platform2 || exit 1
-mkdir "${pkgdir}"
-cd "${pkgdir}"
-# Trim platform2, only common-mk is needed.
-cp -a ../platform2/{common-mk,.gn} .
-
-# Download libchrome source and apply Chrome OS's patches.
-git clone --branch "${branch}" https://chromium.googlesource.com/aosp/platform/external/libchrome || exit 1
-cd libchrome
-rm -rf .git
-while read -r patch; do
- patch -p1 < "libchrome_tools/patches/${patch}"
-done < <(grep -E '^[^#]' "libchrome_tools/patches/patches")
-
-# Clean up temporary platform2 checkout.
-cd ../..
-rm -rf platform2
-
-# Debian requires creating .orig.tar.gz.
-tar czf "${origtar}" "${pkgdir}"
-
-# Debianize the source.
-cd "${pkgdir}"
-yes | debmake || exit 1
-cp -aT "${scriptdir}/debian/" "${tmpdir}/${pkgdir}/debian/"
-
-# Build source package and binary package.
-cd "${tmpdir}/${pkgdir}"
-dpkg-buildpackage --no-sign || exit 1
-
-# Copy the results to output dir.
-cd "${tmpdir}"
-mkdir -p "${outdir}/src"
-cp *.dsc *.orig.tar.gz *.debian.tar.xz "${outdir}/src"
-cp *.deb "${outdir}"
-cd /
-
-echo Removing temporary directory "${tmpdir}".
-rm -rf "${tmpdir}"
-
-echo Done. Check out Debian source package in "${outdir}".
diff --git a/system/build/dpkg/libchrome/debian/changelog b/system/build/dpkg/libchrome/debian/changelog
index 3cdedf6890..e8985eae22 100644
--- a/system/build/dpkg/libchrome/debian/changelog
+++ b/system/build/dpkg/libchrome/debian/changelog
@@ -1,5 +1,5 @@
-libchrome (780652-1) buster; urgency=low
+libchrome (930012-1) bullseye; urgency=low
- * Initial release.
+ * Upgrade to BASE_VER = 930012
- -- Sonny Sasaka <sonnysasaka@chromium.org> Fri, 19 Mar 2021 19:41:40 +0000
+ -- Abhishek Pandit-Subedi <abhishekpandit@chromium.org> Fri, 11 Feb 2022 14:56:00 +0000
diff --git a/system/build/dpkg/libchrome/debian/control b/system/build/dpkg/libchrome/debian/control
index d804b4d88d..b11c23fbc2 100644
--- a/system/build/dpkg/libchrome/debian/control
+++ b/system/build/dpkg/libchrome/debian/control
@@ -18,7 +18,8 @@ Build-Depends:
googletest,
libre2-dev,
libdouble-conversion-dev,
- libssl-dev
+ libssl-dev,
+ libabsl-dev
Package: libchrome
Architecture: any
diff --git a/system/build/dpkg/libchrome/debian/install_headers.sh b/system/build/dpkg/libchrome/debian/install_headers.sh
index 19cb5efa80..817f1a6efc 100755
--- a/system/build/dpkg/libchrome/debian/install_headers.sh
+++ b/system/build/dpkg/libchrome/debian/install_headers.sh
@@ -5,9 +5,12 @@ destdir="$1"
header_dirs=(
base
base/allocator
+ base/allocator/partition_allocator
+ base/allocator/partition_allocator/starscan
base/containers
base/debug
base/files
+ base/functional
base/hash
base/i18n
base/json
@@ -17,6 +20,7 @@ header_dirs=(
base/numerics
base/posix
base/process
+ base/ranges
base/strings
base/synchronization
base/system
@@ -33,13 +37,18 @@ header_dirs=(
base/timer
base/trace_event
base/trace_event/common
+ base/types
build
components/policy
components/policy/core/common
testing/gmock/include/gmock
testing/gtest/include/gtest
dbus
- )
+ third_party/abseil-cpp/absl/types
+ third_party/perfetto/include/perfetto/tracing/
+ third_party/perfetto/include/perfetto/protozero/
+ third_party/perfetto/protos/perfetto/trace/track_event/
+)
# Install header files.
for d in "${header_dirs[@]}" ; do
diff --git a/system/build/dpkg/libchrome/debian/libchrome.install.docker b/system/build/dpkg/libchrome/debian/libchrome.install.docker
new file mode 100644
index 0000000000..b4034e7457
--- /dev/null
+++ b/system/build/dpkg/libchrome/debian/libchrome.install.docker
@@ -0,0 +1,5 @@
+out/Release/lib/libbase*.so /usr/lib/x86_64-linux-gnu
+out/Release/libbase*.a /usr/lib/x86_64-linux-gnu
+out/Release/obj/libchrome/libchrome*.pc /usr/lib/x86_64-linux-gnu/pkgconfig
+usr/include /usr
+
diff --git a/system/build/dpkg/libchrome/debian/patches/0001-Fix-build-issues-on-930012.patch b/system/build/dpkg/libchrome/debian/patches/0001-Fix-build-issues-on-930012.patch
new file mode 100644
index 0000000000..61d044b4fb
--- /dev/null
+++ b/system/build/dpkg/libchrome/debian/patches/0001-Fix-build-issues-on-930012.patch
@@ -0,0 +1,37 @@
+From 1153211a5615156f450a4f521da284a7df4d4e5f Mon Sep 17 00:00:00 2001
+From: Abhishek Pandit-Subedi <abhishekpandit@google.com>
+Date: Mon, 14 Feb 2022 14:40:41 -0800
+Subject: [PATCH] Fix build issues on 930012
+
+---
+ BUILD.gn | 1 +
+ base/command_line.h | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/libchrome/BUILD.gn b/libchrome/BUILD.gn
+index 292c08565a..dbe3fb0981 100644
+--- a/libchrome/BUILD.gn
++++ b/libchrome/BUILD.gn
+@@ -42,6 +42,7 @@ config("libchrome_config") {
+ "-Wno-unreachable-code-return",
+ "-Wno-unused-local-typedefs",
+ "-Xclang-only=-Wno-char-subscripts",
++ "-Wno-implicit-int-float-conversion",
+ ]
+
+ # Address sanitizer + coverage builds do not support -z,defs.
+diff --git a/libchrome/base/command_line.h b/libchrome/base/command_line.h
+index 706726a73e..ad0281283a 100644
+--- a/libchrome/base/command_line.h
++++ b/libchrome/base/command_line.h
+@@ -19,6 +19,7 @@
+ #include <stddef.h>
+ #include <functional>
+ #include <map>
++#include <memory>
+ #include <string>
+ #include <vector>
+
+--
+2.35.1.265.g69c8d7142f-goog
+
diff --git a/system/build/dpkg/libchrome-822064/debian/patches/0001-Remove-absl-from-pkgconfig.patch b/system/build/dpkg/libchrome/debian/patches/0001-Remove-absl-from-pkgconfig.patch
index 73b8c48cd6..73b8c48cd6 100644
--- a/system/build/dpkg/libchrome-822064/debian/patches/0001-Remove-absl-from-pkgconfig.patch
+++ b/system/build/dpkg/libchrome/debian/patches/0001-Remove-absl-from-pkgconfig.patch
diff --git a/system/build/dpkg/libchrome/debian/patches/0001-common-mk-rebase_path-output-location-of-generate-pc.patch b/system/build/dpkg/libchrome/debian/patches/0001-common-mk-rebase_path-output-location-of-generate-pc.patch
deleted file mode 100644
index 418efcc475..0000000000
--- a/system/build/dpkg/libchrome/debian/patches/0001-common-mk-rebase_path-output-location-of-generate-pc.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 04fa5e1ade08696b5a2cc3b65bf0fd26c43251c7 Mon Sep 17 00:00:00 2001
-From: Sonny Sasaka <sonnysasaka@chromium.org>
-Date: Fri, 19 Mar 2021 11:17:43 -0700
-Subject: [PATCH] common-mk: rebase_path output location of generate-pc.py
-
-Without rebase_path, the generate-pc.py would be called like
-`generate-pc.py --output //out/Release` if the output is inside the
-source directory and this gn path isn't recognized as a generic
-filesystem path.
-
-BUG=b:183216216
-TEST=with modp_b64, call
-$ gn gen out/Release --args=...
-$ ninja
-
-Change-Id: Ic9d9b3d01d52d483e3d81ca2e8d514b47900f5bb
----
- common-mk/pkg_config.gni | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/common-mk/pkg_config.gni b/common-mk/pkg_config.gni
-index 24e2cf1401..b2c58845d4 100644
---- a/common-mk/pkg_config.gni
-+++ b/common-mk/pkg_config.gni
-@@ -84,7 +84,7 @@ template("generate_pkg_config") {
- outputs = [ "${target_out_dir}/${output_name}.pc" ]
-
- script = "//common-mk/generate-pc.py"
-- args = [ "--output" ] + outputs + [ "--name=" + name ]
-+ args = [ "--output" ] + rebase_path(outputs) + [ "--name=" + name ]
- if (defined(description)) {
- args += [ "--description=" + description ]
- }
---
-2.29.2
-
diff --git a/system/build/dpkg/libchrome/debian/patches/series b/system/build/dpkg/libchrome/debian/patches/series
index 5a26f7be70..de8be97780 100644
--- a/system/build/dpkg/libchrome/debian/patches/series
+++ b/system/build/dpkg/libchrome/debian/patches/series
@@ -1,3 +1,4 @@
-0001-common-mk-rebase_path-output-location-of-generate-pc.patch
0001-Add-missing-includes.patch
0001-rebase_path-for-write_args.patch
+0001-Remove-absl-from-pkgconfig.patch
+0001-Fix-build-issues-on-930012.patch
diff --git a/system/build/dpkg/libchrome/debian/rules b/system/build/dpkg/libchrome/debian/rules
index 6ac17835c4..3374099c98 100755
--- a/system/build/dpkg/libchrome/debian/rules
+++ b/system/build/dpkg/libchrome/debian/rules
@@ -3,17 +3,17 @@
# gn args
defines =
defines += pkg_config=\"pkg-config\"
-defines += libbase_ver=\"780652\"
+defines += libbase_ver=\"930012\"
defines += platform2_root=\"$(shell pwd)/\"
defines += platform_subdir=\"libchrome\"
defines += cxx=\"clang++\"
defines += cc=\"clang\"
defines += ar=\"ar\"
-defines += external_cxxflags=[\"-I/usr/src/googletest/googletest/include\", \"-I/usr/src/googletest/googlemock/include\"]
-defines += external_ldflags=[\"-latomic\"]
+defines += external_cxxflags=[\"-DNDEBUG\", \"-I/usr/src/googletest/googletest/include\", \"-I/usr/src/googletest/googlemock/include\", \"-Wno-unknown-warning-option\", \"-Wno-unused-command-line-argument\", \"-Wno-implicit-int-float-conversion\"]
+defines += external_ldflags=[\"-latomic\", \"-labsl_base\", \"-labsl_bad_variant_access\", \"-labsl_bad_optional_access\"]
defines += enable_werror=false
defines += libdir=\"/usr/lib\"
-defines += use={mojo=false asan=false coverage=false crypto=true dbus=true fuzzer=false timers=true cros_host=false profiling=false tcmalloc=false}
+defines += use={mojo=false asan=false coverage=false crypto=true dbus=true fuzzer=false timers=true cros_host=false profiling=false tcmalloc=false test=false}
# handle parallel build options
njobs=1
diff --git a/system/build/dpkg/libchrome/gen-src-pkg.sh b/system/build/dpkg/libchrome/gen-src-pkg.sh
index 3cee0e4612..01390f126d 100755
--- a/system/build/dpkg/libchrome/gen-src-pkg.sh
+++ b/system/build/dpkg/libchrome/gen-src-pkg.sh
@@ -7,25 +7,34 @@ if [ -z "$1" ]; then
fi
outdir="$1"
-pkgdir=libchrome-780652
-origtar=libchrome_780652.orig.tar.gz
+pkgdir=libchrome-930012
+origtar=libchrome_930012.orig.tar.gz
scriptdir="$( cd "$( dirname "$0" )" && pwd )"
-branch=release-R90-13816.B
+
+# Pin the libchrome branch + commit
+libchrome_branch=master
+libchrome_commit=4b86c42f09b7c8d88b0233c60f59bafeb4d8df19
+
+# Pin the platform2 branch + commit
+platform2_branch=main
+platform2_commit=4567e833015453b3ea322eec1201cc41ecdfdec0
tmpdir=$(mktemp -d)
echo Generating source package in "${tmpdir}".
# Download platform2 source.
cd "${tmpdir}"
-git clone --branch "${branch}" https://chromium.googlesource.com/chromiumos/platform2 || exit 1
+git clone --branch "${platform2_branch}" https://chromium.googlesource.com/chromiumos/platform2 || exit 1
+(cd platform2 && git checkout "${platform2_commit}")
mkdir "${pkgdir}"
cd "${pkgdir}"
# Trim platform2, only common-mk is needed.
cp -a ../platform2/{common-mk,.gn} .
# Download libchrome source and apply Chrome OS's patches.
-git clone --branch "${branch}" https://chromium.googlesource.com/aosp/platform/external/libchrome || exit 1
+git clone --branch "${libchrome_branch}" https://chromium.googlesource.com/aosp/platform/external/libchrome || exit 1
cd libchrome
+git checkout "${libchrome_commit}"
rm -rf .git
while read -r patch; do
patch -p1 < "libchrome_tools/patches/${patch}"
@@ -43,6 +52,14 @@ cd "${pkgdir}"
yes | debmake || exit 1
cp -aT "${scriptdir}/debian/" "${tmpdir}/${pkgdir}/debian/"
+# If building for docker, use the right install script.
+if [ ! -z "${LIBCHROME_DOCKER}" ]; then
+ mv "${tmpdir}/${pkgdir}/debian/libchrome.install.docker" \
+ "${tmpdir}/${pkgdir}/debian/libchrome.install"
+else
+ rm -f "${tmpdir}/${pkgdir}/debian/libchrome.install.docker"
+fi
+
# Build source package and binary package.
cd "${tmpdir}/${pkgdir}"
dpkg-buildpackage --no-sign || exit 1
diff --git a/system/build/dpkg/modp_b64/debian/modp-b64.install.docker b/system/build/dpkg/modp_b64/debian/modp-b64.install.docker
new file mode 100644
index 0000000000..a028ca4955
--- /dev/null
+++ b/system/build/dpkg/modp_b64/debian/modp-b64.install.docker
@@ -0,0 +1,3 @@
+modp_b64/modp_b64 /usr/include
+out/Release/libmodp_b64.a /usr/lib/x86_64-linux-gnu
+out/Release/obj/modp_b64/libmodp_b64.pc /usr/lib/x86_64-linux-gnu/pkgconfig
diff --git a/system/build/dpkg/modp_b64/gen-src-pkg.sh b/system/build/dpkg/modp_b64/gen-src-pkg.sh
index cc22f678f2..5e62160159 100755
--- a/system/build/dpkg/modp_b64/gen-src-pkg.sh
+++ b/system/build/dpkg/modp_b64/gen-src-pkg.sh
@@ -40,6 +40,15 @@ cd "${pkgdir}"
yes | debmake || exit 1
cp -aT "${scriptdir}/debian/" "${tmpdir}/${pkgdir}/debian/"
+# If building for docker, use the right install script.
+if [ ! -z "${MODP_DOCKER}" ]; then
+ mv "${tmpdir}/${pkgdir}/debian/modp-b64.install.docker" \
+ "${tmpdir}/${pkgdir}/debian/modp-b64.install"
+else
+ rm -f "${tmpdir}/${pkgdir}/debian/modp-b64.install.docker"
+fi
+
+
# Build source package and binary package.
cd "${tmpdir}/${pkgdir}"
dpkg-buildpackage --no-sign || exit 1
diff --git a/system/common/message_loop_thread.h b/system/common/message_loop_thread.h
index 7420dbcb26..ece1d0ffbc 100644
--- a/system/common/message_loop_thread.h
+++ b/system/common/message_loop_thread.h
@@ -48,6 +48,9 @@ class MessageLoopThread final {
explicit MessageLoopThread(const std::string& thread_name);
explicit MessageLoopThread(const std::string& thread_name, bool is_main);
+ MessageLoopThread(const MessageLoopThread&) = delete;
+ MessageLoopThread& operator=(const MessageLoopThread&) = delete;
+
/**
* Destroys the message loop thread automatically when it goes out of scope
*/
@@ -199,8 +202,6 @@ class MessageLoopThread final {
bool shutting_down_;
bool is_main_;
::rust::Box<shim::rust::MessageLoopThread>* rust_thread_ = nullptr;
-
- DISALLOW_COPY_AND_ASSIGN(MessageLoopThread);
};
inline std::ostream& operator<<(std::ostream& os,
diff --git a/system/common/once_timer.h b/system/common/once_timer.h
index ca7185d001..d708ed97d6 100644
--- a/system/common/once_timer.h
+++ b/system/common/once_timer.h
@@ -39,6 +39,9 @@ class MessageLoopThread;
class OnceTimer final {
public:
OnceTimer() {}
+ OnceTimer(const OnceTimer&) = delete;
+ OnceTimer& operator=(const OnceTimer&) = delete;
+
~OnceTimer();
/**
@@ -84,8 +87,6 @@ class OnceTimer final {
void CancelClosure(std::promise<void> promise);
void RunTask();
-
- DISALLOW_COPY_AND_ASSIGN(OnceTimer);
};
} // namespace common
diff --git a/system/common/repeating_timer.h b/system/common/repeating_timer.h
index 24eae67d09..5c2c9e3169 100644
--- a/system/common/repeating_timer.h
+++ b/system/common/repeating_timer.h
@@ -39,6 +39,9 @@ class MessageLoopThread;
class RepeatingTimer final {
public:
RepeatingTimer() : expected_time_next_task_us_(0) {}
+ RepeatingTimer(const RepeatingTimer&) = delete;
+ RepeatingTimer& operator=(const RepeatingTimer&) = delete;
+
~RepeatingTimer();
/**
@@ -85,8 +88,6 @@ class RepeatingTimer final {
void CancelClosure(std::promise<void> promise);
void RunTask();
-
- DISALLOW_COPY_AND_ASSIGN(RepeatingTimer);
};
} // namespace common
diff --git a/system/device/include/controller.h b/system/device/include/controller.h
index d65ab32d90..d2ee43833e 100644
--- a/system/device/include/controller.h
+++ b/system/device/include/controller.h
@@ -114,6 +114,7 @@ typedef struct controller_t {
void (*set_ble_resolving_list_max_size)(int resolving_list_max_size);
uint8_t* (*get_local_supported_codecs)(uint8_t* number_of_codecs);
uint8_t (*get_le_all_initiating_phys)(void);
+ uint8_t (*clear_event_filter)(void);
} controller_t;
diff --git a/system/embdrv/lc3/fuzzer/liblc3encoder_fuzzer.cpp b/system/embdrv/lc3/fuzzer/liblc3encoder_fuzzer.cpp
index 7979bc7047..767dba495e 100644
--- a/system/embdrv/lc3/fuzzer/liblc3encoder_fuzzer.cpp
+++ b/system/embdrv/lc3/fuzzer/liblc3encoder_fuzzer.cpp
@@ -37,7 +37,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
void* lc3_encoder_mem = nullptr;
lc3_encoder_mem = malloc(enc_size);
- lc3_encoder_t lc3_encoder = lc3_setup_encoder(dt_us, sr_hz, lc3_encoder_mem);
+ lc3_encoder_t lc3_encoder =
+ lc3_setup_encoder(dt_us, sr_hz, 0, lc3_encoder_mem);
std::vector<uint8_t> output(output_byte_count);
lc3_encode(lc3_encoder, (const int16_t*)input_frames.data(), 1,
diff --git a/system/embdrv/lc3/include/lc3.h b/system/embdrv/lc3/include/lc3.h
index ec53f2b162..f8dc8b3492 100644
--- a/system/embdrv/lc3/include/lc3.h
+++ b/system/embdrv/lc3/include/lc3.h
@@ -205,6 +205,9 @@ int lc3_delay_samples(int dt_us, int sr_hz);
* dt_us Frame duration in us, 7500 or 10000
* sr_hz Samplerate in Hz, 8000, 16000, 24000, 32000 or 48000
* return Size of then encoder in bytes, 0 on bad parameters
+ *
+ * The `sr_hz` parameter is the samplerate of the PCM input stream,
+ * and will match `sr_pcm_hz` of `lc3_setup_encoder()`.
*/
unsigned lc3_encoder_size(int dt_us, int sr_hz);
@@ -212,10 +215,18 @@ unsigned lc3_encoder_size(int dt_us, int sr_hz);
* Setup encoder
* dt_us Frame duration in us, 7500 or 10000
* sr_hz Samplerate in Hz, 8000, 16000, 24000, 32000 or 48000
+ * sr_pcm_hz Input samplerate, downsampling option of input, or 0
* mem Encoder memory space, aligned to pointer type
* return Encoder as an handle, NULL on bad parameters
+ *
+ * The `sr_pcm_hz` parameter is a downsampling option of PCM input,
+ * the value `0` fallback to the samplerate of the encoded stream `sr_hz`.
+ * When used, `sr_pcm_hz` is intended to be higher or equal to the encoder
+ * samplerate `sr_hz`. The size of the context needed, given by
+ * `lc3_encoder_size()` will be set accordingly to `sr_pcm_hz`.
*/
-lc3_encoder_t lc3_setup_encoder(int dt_us, int sr_hz, void *mem);
+lc3_encoder_t lc3_setup_encoder(
+ int dt_us, int sr_hz, int sr_pcm_hz, void *mem);
/**
* Encode a frame
@@ -233,6 +244,9 @@ int lc3_encode(lc3_encoder_t encoder,
* dt_us Frame duration in us, 7500 or 10000
* sr_hz Samplerate in Hz, 8000, 16000, 24000, 32000 or 48000
* return Size of then decoder in bytes, 0 on bad parameters
+ *
+ * The `sr_hz` parameter is the samplerate of the PCM output stream,
+ * and will match `sr_pcm_hz` of `lc3_setup_decoder()`.
*/
unsigned lc3_decoder_size(int dt_us, int sr_hz);
@@ -240,10 +254,18 @@ unsigned lc3_decoder_size(int dt_us, int sr_hz);
* Setup decoder
* dt_us Frame duration in us, 7500 or 10000
* sr_hz Samplerate in Hz, 8000, 16000, 24000, 32000 or 48000
+ * sr_pcm_hz Output samplerate, upsampling option of output (or 0)
* mem Decoder memory space, aligned to pointer type
* return Decoder as an handle, NULL on bad parameters
+ *
+ * The `sr_pcm_hz` parameter is an upsampling option of PCM output,
+ * the value `0` fallback to the samplerate of the decoded stream `sr_hz`.
+ * When used, `sr_pcm_hz` is intended to be higher or equal to the decoder
+ * samplerate `sr_hz`. The size of the context needed, given by
+ * `lc3_decoder_size()` will be set accordingly to `sr_pcm_hz`.
*/
-lc3_decoder_t lc3_setup_decoder(int dt_us, int sr_hz, void *mem);
+lc3_decoder_t lc3_setup_decoder(
+ int dt_us, int sr_hz, int sr_pcm_hz, void *mem);
/**
* Decode a frame
diff --git a/system/embdrv/lc3/include/lc3_private.h b/system/embdrv/lc3/include/lc3_private.h
index d6037d57e4..c59ff53d46 100644
--- a/system/embdrv/lc3/include/lc3_private.h
+++ b/system/embdrv/lc3/include/lc3_private.h
@@ -97,7 +97,7 @@ typedef struct lc3_spec_analysis {
struct lc3_encoder {
enum lc3_dt dt;
- enum lc3_srate sr;
+ enum lc3_srate sr, sr_pcm;
lc3_attdet_analysis_t attdet;
lc3_ltpf_analysis_t ltpf;
@@ -134,7 +134,7 @@ typedef struct lc3_plc_state {
struct lc3_decoder {
enum lc3_dt dt;
- enum lc3_srate sr;
+ enum lc3_srate sr, sr_pcm;
lc3_ltpf_synthesis_t ltpf;
lc3_plc_state_t plc;
diff --git a/system/embdrv/lc3/src/bits.h b/system/embdrv/lc3/src/bits.h
index d1fc45033d..388bba1611 100644
--- a/system/embdrv/lc3/src/bits.h
+++ b/system/embdrv/lc3/src/bits.h
@@ -292,7 +292,7 @@ static inline unsigned lc3_get_symbol(
if (ac->error)
ac->low = 0;
- unsigned s = 16;
+ int s = 16;
if (ac->low < range * symbols[s].low) {
s >>= 1;
diff --git a/system/embdrv/lc3/src/lc3.c b/system/embdrv/lc3/src/lc3.c
index bff7dc30c9..6fd7575014 100644
--- a/system/embdrv/lc3/src/lc3.c
+++ b/system/embdrv/lc3/src/lc3.c
@@ -153,7 +153,7 @@ static void load_s16(
struct lc3_encoder *encoder, const int16_t *pcm, int pitch)
{
enum lc3_dt dt = encoder->dt;
- enum lc3_srate sr = encoder->sr;
+ enum lc3_srate sr = encoder->sr_pcm;
float *xs = encoder->xs;
int ns = LC3_NS(dt, sr);
@@ -172,23 +172,25 @@ static void analyze(struct lc3_encoder *encoder,
{
enum lc3_dt dt = encoder->dt;
enum lc3_srate sr = encoder->sr;
+ enum lc3_srate sr_pcm = encoder->sr_pcm;
+ int ns = LC3_NS(dt, sr_pcm);
+ int nd = LC3_ND(dt, sr_pcm);
+
float *xs = encoder->xs;
float *xf = encoder->xf;
- int ns = LC3_NS(dt, sr);
- int nd = LC3_ND(dt, sr);
/* --- Temporal --- */
- bool att = lc3_attdet_run(dt, sr, nbytes, &encoder->attdet, xs);
+ bool att = lc3_attdet_run(dt, sr_pcm, nbytes, &encoder->attdet, xs);
side->pitch_present =
- lc3_ltpf_analyse(dt, sr, &encoder->ltpf, xs, &side->ltpf);
+ lc3_ltpf_analyse(dt, sr_pcm, &encoder->ltpf, xs, &side->ltpf);
/* --- Spectral --- */
float e[LC3_NUM_BANDS];
- lc3_mdct_forward(dt, sr, xs, xf);
+ lc3_mdct_forward(dt, sr_pcm, sr, xs, xf);
memmove(xs - nd, xs + ns-nd, nd * sizeof(float));
bool nn_flag = lc3_energy_compute(dt, sr, xf, e);
@@ -260,26 +262,32 @@ unsigned lc3_encoder_size(int dt_us, int sr_hz)
/**
* Setup encoder
*/
-struct lc3_encoder *lc3_setup_encoder(int dt_us, int sr_hz, void *mem)
+struct lc3_encoder *lc3_setup_encoder(
+ int dt_us, int sr_hz, int sr_pcm_hz, void *mem)
{
+ if (sr_pcm_hz <= 0)
+ sr_pcm_hz = sr_hz;
+
enum lc3_dt dt = resolve_dt(dt_us);
enum lc3_srate sr = resolve_sr(sr_hz);
+ enum lc3_srate sr_pcm = resolve_sr(sr_pcm_hz);
- if (dt >= LC3_NUM_DT || sr >= LC3_NUM_SRATE || !mem)
+ if (dt >= LC3_NUM_DT || sr_pcm >= LC3_NUM_SRATE || sr > sr_pcm || !mem)
return NULL;
struct lc3_encoder *encoder = mem;
- int ns = LC3_NS(dt, sr);
- int nd = LC3_ND(dt, sr);
+ int ns = LC3_NS(dt, sr_pcm);
+ int nd = LC3_ND(dt, sr_pcm);
*encoder = (struct lc3_encoder){
.dt = dt, .sr = sr,
+ .sr_pcm = sr_pcm,
.xs = encoder->s + nd,
.xf = encoder->s + nd+ns,
};
memset(encoder->s, 0,
- LC3_ENCODER_BUFFER_COUNT(dt_us, sr_hz) * sizeof(float));
+ LC3_ENCODER_BUFFER_COUNT(dt_us, sr_pcm_hz) * sizeof(float));
return encoder;
}
@@ -324,7 +332,7 @@ static void store_s16(
struct lc3_decoder *decoder, int16_t *pcm, int pitch)
{
enum lc3_dt dt = decoder->dt;
- enum lc3_srate sr = decoder->sr;
+ enum lc3_srate sr = decoder->sr_pcm;
float *xs = decoder->xs;
int ns = LC3_NS(dt, sr);
@@ -391,8 +399,9 @@ static void synthesize(struct lc3_decoder *decoder,
{
enum lc3_dt dt = decoder->dt;
enum lc3_srate sr = decoder->sr;
- int ns = LC3_NS(dt, sr);
- int nh = LC3_NH(sr);
+ enum lc3_srate sr_pcm = decoder->sr_pcm;
+ int ns = LC3_NS(dt, sr_pcm);
+ int nh = LC3_NH(sr_pcm);
float *xf = decoder->xs;
float *xg = decoder->xg;
@@ -408,15 +417,15 @@ static void synthesize(struct lc3_decoder *decoder,
lc3_sns_synthesize(dt, sr, &side->sns, xf, xg);
- lc3_mdct_inverse(dt, sr, xg, xd, xs);
+ lc3_mdct_inverse(dt, sr_pcm, sr, xg, xd, xs);
} else {
lc3_plc_synthesize(dt, sr, &decoder->plc, xg, xf);
- lc3_mdct_inverse(dt, sr, xf, xd, xs);
+ lc3_mdct_inverse(dt, sr_pcm, sr, xf, xd, xs);
}
- lc3_ltpf_synthesize(dt, sr, nbytes, &decoder->ltpf,
+ lc3_ltpf_synthesize(dt, sr_pcm, nbytes, &decoder->ltpf,
side && side->pitch_present ? &side->ltpf : NULL, xs);
memmove(xs - nh, xs - nh+ns, nh * sizeof(*xs));
@@ -438,21 +447,27 @@ unsigned lc3_decoder_size(int dt_us, int sr_hz)
/**
* Setup decoder
*/
-struct lc3_decoder *lc3_setup_decoder(int dt_us, int sr_hz, void *mem)
+struct lc3_decoder *lc3_setup_decoder(
+ int dt_us, int sr_hz, int sr_pcm_hz, void *mem)
{
+ if (sr_pcm_hz <= 0)
+ sr_pcm_hz = sr_hz;
+
enum lc3_dt dt = resolve_dt(dt_us);
enum lc3_srate sr = resolve_sr(sr_hz);
+ enum lc3_srate sr_pcm = resolve_sr(sr_pcm_hz);
- if (dt >= LC3_NUM_DT || sr >= LC3_NUM_SRATE || !mem)
+ if (dt >= LC3_NUM_DT || sr_pcm >= LC3_NUM_SRATE || sr > sr_pcm || !mem)
return NULL;
struct lc3_decoder *decoder = mem;
- int nh = LC3_NH(sr);
- int ns = LC3_NS(dt, sr);
- int nd = LC3_ND(dt, sr);
+ int nh = LC3_NH(sr_pcm);
+ int ns = LC3_NS(dt, sr_pcm);
+ int nd = LC3_ND(dt, sr_pcm);
*decoder = (struct lc3_decoder){
.dt = dt, .sr = sr,
+ .sr_pcm = sr_pcm,
.xs = decoder->s + nh,
.xd = decoder->s + nh+ns,
.xg = decoder->s + nh+ns+nd,
@@ -461,7 +476,7 @@ struct lc3_decoder *lc3_setup_decoder(int dt_us, int sr_hz, void *mem)
lc3_plc_reset(&decoder->plc);
memset(decoder->s, 0,
- LC3_DECODER_BUFFER_COUNT(dt_us, sr_hz) * sizeof(float));
+ LC3_DECODER_BUFFER_COUNT(dt_us, sr_pcm_hz) * sizeof(float));
return decoder;
}
@@ -472,8 +487,6 @@ struct lc3_decoder *lc3_setup_decoder(int dt_us, int sr_hz, void *mem)
int lc3_decode(struct lc3_decoder *decoder,
const void *in, int nbytes, int16_t *pcm, int pitch)
{
- struct side_data side;
-
/* --- Check parameters --- */
if (!decoder)
@@ -485,6 +498,8 @@ int lc3_decode(struct lc3_decoder *decoder,
/* --- Processing --- */
+ struct side_data side;
+
int ret = !in || (decode(decoder, in, nbytes, &side) < 0);
synthesize(decoder, ret ? NULL : &side, nbytes);
diff --git a/system/embdrv/lc3/src/mdct.c b/system/embdrv/lc3/src/mdct.c
index 8e95284f81..c02904a1be 100644
--- a/system/embdrv/lc3/src/mdct.c
+++ b/system/embdrv/lc3/src/mdct.c
@@ -464,9 +464,10 @@ static void imdct_window(enum lc3_dt dt, enum lc3_srate sr,
* Forward MDCT transformation
*/
void lc3_mdct_forward(enum lc3_dt dt, enum lc3_srate sr,
- const float *x, float *y)
+ enum lc3_srate sr_dst, const float *x, float *y)
{
const struct lc3_mdct_rot_def *rot = lc3_mdct_rot[dt][sr];
+ int nf = LC3_NS(dt, sr_dst);
int ns = LC3_NS(dt, sr);
union { float *f; struct lc3_complex *z; } u = { .f = y };
@@ -476,16 +477,17 @@ void lc3_mdct_forward(enum lc3_dt dt, enum lc3_srate sr,
mdct_pre_fft(rot, u.f, u.z);
u.z = fft(false, u.z, ns/2, u.z, z);
- mdct_post_fft(rot, u.z, y, sqrtf(2.f / ns));
+ mdct_post_fft(rot, u.z, y, sqrtf( (2.f*nf) / (ns*ns) ));
}
/**
* Inverse MDCT transformation
*/
void lc3_mdct_inverse(enum lc3_dt dt, enum lc3_srate sr,
- const float *x, float *d, float *y)
+ enum lc3_srate sr_src, const float *x, float *d, float *y)
{
const struct lc3_mdct_rot_def *rot = lc3_mdct_rot[dt][sr];
+ int nf = LC3_NS(dt, sr_src);
int ns = LC3_NS(dt, sr);
struct lc3_complex buffer[ns/2];
@@ -494,7 +496,7 @@ void lc3_mdct_inverse(enum lc3_dt dt, enum lc3_srate sr,
imdct_pre_fft(rot, x, z);
z = fft(true, z, ns/2, z, u.z);
- imdct_post_fft(rot, z, u.f, sqrtf(2.f / ns));
+ imdct_post_fft(rot, z, u.f, sqrtf(2.f / nf));
imdct_window(dt, sr, u.f, d, y);
}
diff --git a/system/embdrv/lc3/src/mdct.h b/system/embdrv/lc3/src/mdct.h
index c2c3bdcb85..27e48f40e3 100644
--- a/system/embdrv/lc3/src/mdct.h
+++ b/system/embdrv/lc3/src/mdct.h
@@ -32,6 +32,7 @@
/**
* Forward MDCT transformation
* dt, sr Duration and samplerate (size of the transform)
+ * sr_dst Samplerate destination, scale transforam accordingly
* x [-nd..-1] Previous, [0..ns-1] Current samples
* y Output `ns` frequency coefficients
*
@@ -40,18 +41,19 @@
* nd: `ns` * 5/ 8 for 10ms frame duration
*/
void lc3_mdct_forward(enum lc3_dt dt, enum lc3_srate sr,
- const float *x, float *y);
+ enum lc3_srate sr_dst, const float *x, float *y);
/**
* Inverse MDCT transformation
* dt, sr Duration and samplerate (size of the transform)
+ * sr_src Samplerate source, scale transforam accordingly
* x, d Frequency coefficients and delayed buffer
* y, d Output `ns` samples and `nd` delayed ones
*
* `x` and `y` can be the same buffer
*/
void lc3_mdct_inverse(enum lc3_dt dt, enum lc3_srate sr,
- const float *x, float *d, float *y);
+ enum lc3_srate sr_src, const float *x, float *d, float *y);
#endif /* __LC3_MDCT_H */
diff --git a/system/embdrv/lc3/src/tns.c b/system/embdrv/lc3/src/tns.c
index 0ddd72caa4..8545d78380 100644
--- a/system/embdrv/lc3/src/tns.c
+++ b/system/embdrv/lc3/src/tns.c
@@ -448,7 +448,7 @@ void lc3_tns_get_data(lc3_bits_t *bits,
lc3_tns_order_models + data->lpc_weighting);
for (int i = 0; i < data->rc_order[f]; i++)
- data->rc[f][i] = lc3_get_symbol(bits,
+ data->rc[f][i] = (int)lc3_get_symbol(bits,
lc3_tns_coeffs_models + i) - 8;
}
}
diff --git a/system/embdrv/lc3_dec/Android.bp b/system/embdrv/lc3_dec/Android.bp
deleted file mode 100644
index 36c4099518..0000000000
--- a/system/embdrv/lc3_dec/Android.bp
+++ /dev/null
@@ -1,69 +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_library_static {
- name: "liblc3codec",
- host_supported: true,
- apex_available: [
-
- "//apex_available:platform",
- "com.android.bluetooth"
- ],
- defaults: ["fluoride_defaults"],
- srcs: [
- "Common/*.cpp",
- "Common/fft/*.c",
- "Common/Tables/*.cpp",
- "Decoder/*.cpp",
- "TestSupport/DatapointsAndroid.cpp",
- ],
- cflags: [
- "-Werror",
- "-Wmissing-braces",
- "-Wno-unused-parameter",
- "-Wno-#warnings",
- "-Wuninitialized",
- "-Wno-self-assign",
- "-Wno-implicit-fallthrough",
- ],
- target: {
- android: {
- sanitize: {
- misc_undefined:[
- "unsigned-integer-overflow",
- "signed-integer-overflow",
- "bounds",
- ],
- cfi: true,
- },
- },
- },
- shared_libs: [
- "liblog",
- ],
- export_include_dirs: [
- "Api",
- "Common",
- "Common/fft",
- "Common/Tables",
- "TestSupport",
- ],
-}
-
-cc_fuzz {
- name: "liblc3codec_decoder_fuzzer",
-
- srcs: [
- "fuzzer/liblc3codec_decoder_fuzzer.cpp",
- ],
-
- static_libs: [
- "liblc3codec",
- ],
-} \ No newline at end of file
diff --git a/system/embdrv/lc3_dec/Api/Lc3Config.hpp b/system/embdrv/lc3_dec/Api/Lc3Config.hpp
deleted file mode 100644
index 94469050f8..0000000000
--- a/system/embdrv/lc3_dec/Api/Lc3Config.hpp
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Lc3Config.hpp
- *
- * 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.
- */
-
-#ifndef __LC3_CONFIG_HPP_
-#define __LC3_CONFIG_HPP_
-
-#include <cstdint>
-
-/*
- * The LC3 encoder and decoder have a common set of essential session
- * configuration parameters - see LC3 specification Sections 2.2 "Encoder
- * interfaces" and Section 2.4 "Decoder interfaces" (dr09r07). The set of common
- * session configuration parameters is represented by an instance of class
- * Lc3Config.
- *
- * Lc3Config is designed such that all parameters need to be
- * providing when constructing an instance. Afterwards, success of creation,
- * the actual parameter values, and derived parameter values are provided
- * by corresponding const getter methods or public const fields.
- *
- * When parameters need to be changes, a new instance of Lc3Config has to be
- * created.
- *
- * Instances of Lc3Config are provided to instances of Lc3Encoder and Lc3Decoder
- * when constructing them.
- *
- * The main purpose of Lc3Config is to verify and handle common LC3 session
- * configuration parameters in a consistent way.
- *
- */
-class Lc3Config {
- public:
- /*
- * Enumeration of supported frame durations N_ms = 7.5ms and N_ms = 10ms.
- *
- * Note: although the LC3 specification describes frame duration N_ms as
- * a parameter with floating point values 7.5 and 10.0, we decided
- * to make this parameter a discrete enumeration of supported
- * frame durations. There are too many codec parts that need
- * specifically listed constants dependent on the configured
- * frame duration, so that it never will be possible to chose from a
- * larger set of floating point values for N_ms.
- * Making the data type of N_ms an enumeration supports
- * straight forwards verification that meaningful parameters are given.
- */
- enum class FrameDuration { d10ms, d7p5ms };
-
- // configuration error (see "getErrorStatus")
- static const uint8_t ERROR_FREE = 0x00;
- static const uint8_t INVALID_SAMPLING_RATE = 0x01;
- static const uint8_t INVALID_FRAME_DURATION = 0x02;
- static const uint8_t INVALID_NUMBER_OF_CHANNELS = 0x04;
-
- /*
- * Constructor of an instance of Lc3Config
- * Parameters:
- * (see also see LC3 specification Sections 2.2 "Encoder interfaces"
- * and Section 2.4 "Decoder interfaces" (dr09r07) )
- *
- * Fs_ : Sampling frequency in Hz -> defines public constant Fs
- * Supported values are
- * 8000 Hz
- * 16000 Hz
- * 24000 Hz
- * 32000 Hz
- * 44100 Hz
- * 48000 Hz
- *
- * N_ms_ : Frame duration given by value from enumeration FrameDuration (see
- * above)
- * -> defines public constant N_ms
- * Supported values see enumeration FrameDuration.
- *
- * Nc_ : Number of channels -> defines public constant Nc
- * Supported values are Nc > 0 and Nc < 256 such that device
- * resources are not exhausted. Notes:
- * - Exhausting device resources can mean that there is not enough
- * memory to instantiate the corresponding number of encoders and/or decoders,
- * but also that computing the encoders and/or decoders in real-time is not
- * possible.
- * - The parameter N_c_max described in the LC3 specifciation is
- * not given here, since there is too little knowledge on the target devices
- * where this code may be used.
- *
- */
- Lc3Config(uint16_t Fs_, FrameDuration N_ms_, uint8_t Nc_);
-
- // no default constructor supported
- Lc3Config() = delete;
-
- // Destructor
- virtual ~Lc3Config();
-
- /*
- * Getter "isValid" provides a convenience function that returns true when an
- * instance of Lc3Config could be created without error.
- */
- bool isValid() const;
-
- /*
- * Getter "getErrorStatus" provides details on the success of instantiating
- * Lc3Config. The possible return values are listed as constants in this class
- * (see configuration error constants above)
- */
- uint8_t getErrorStatus() const;
-
- /*
- * Getter "getByteCountFromBitrate" provides the number of bytes available in
- * one encoded frame of one channel (see "nbytes" as described in
- * Section 3.2.5 "Bit budget and bitrate" (dr09r07) )
- *
- * The number of bytes "nbytes" to use for encoding a single channel is a
- * required external input to each single channel LC3 encoder. The same number
- * of bytes (now to be used for decoding) is also a required external input to
- * each single channel LC3 decoder. The corresponding number of bits available
- * in one frame is thus "nbits 8*nbytes". The codec works on a byte boundary,
- * i.e. the variable "nbytes" shall be an integer number. A certain "bitrate"
- * can be converted to a number of bytes "nbytes" where the number of bytes is
- * rounded towards the nearest lower integer.
- *
- * The algorithm is verified from the bitrate corresponding to
- * nbytes = 20 up to the bitrate corresponding to
- * nbytes = 400 per channel for all sampling rates.
- * The LC3 specification does not specify or recommend what bitrate to use for
- * encoding a frame of audio samples. This is specified by the profiles making
- * use of the LC3.
- */
- uint16_t getByteCountFromBitrate(
- uint32_t bitrate) const; // meant for a single channel
-
- /*
- * Getter "getBitrateFromByteCount" provides the bitrate of the codec in bits
- * per second of one channel (see Section 3.2.5 "Bit budget and bitrate"
- * (dr1.0r03) )
- *
- * This is a convenience utility and not directly used by the LC3
- * implementation.
- *
- * The bitrate of the codec in bits per second is
- * "bitrate = ceil(nbits / frame_duration) = ceil(nbits*Fs/NF) =
- * ceil(8*nbytes*Fs/NF)".
- *
- * The LC3 specification does not specify or recommend what bitrate to use for
- * encoding a frame of audio samples. This is specified by the profiles making
- * use of the LC3.
- */
- uint32_t getBitrateFromByteCount(uint16_t nbytes) const;
-
- /*
- * Getter "getFscal" provides a utility used within the LC3 implementation
- * for easier parameter mapping when Fs == 44100
- * (see Section 3.2.2 "Sampling rates" (dr1.0r03) )
- */
- double getFscal() const;
-
- /*
- * Getter "getNmsValue" provides a utility used within the LC3 implementation
- * that converts FrameDuration N_ms enumeration values to duration values in
- * milliseconds.
- */
- double getNmsValue() const;
-
- private:
- // internal utilities used for verifying the given input parameters and
- // computing derived parameters
- uint8_t getFs_ind(uint16_t Fs);
- uint16_t getNF(uint16_t Fs, FrameDuration N_ms);
- uint16_t getNE(uint16_t NF, FrameDuration N_ms);
-
- // errors status set during construction and returned by getErrorStatus()
- uint8_t errorStatus;
-
- public:
- // configuration details -> see also Section 3.1.2 "Mathematical symbols"
- // (dr09r07)
- const uint16_t Fs; // Sampling rate (in Hz)
- const uint8_t Fs_ind; // Sampling rate index (see also Section 3.2.2
- // "Sampling rates" (dr09r07)
- const FrameDuration N_ms; // Frame duration -> see Lc3Config constructor
- // documentation Note: that the actual frame
- // duration is longer by a factor of 480/441
- // if the sampling rate is 44100 Hz
- const uint16_t NF; // Number of samples processed in one frame of one channel
- // (also known as frame size)
- const uint16_t
- NE; // Number of encoded spectral lines (per frame and channel)
- const uint16_t Z; // Number of leading zeros in MDCT window
- const uint8_t Nc; // Number of channels
- const uint8_t N_b; // Number of bands
-};
-
-#endif // __LC3_CONFIG_HPP_
diff --git a/system/embdrv/lc3_dec/Api/Lc3Decoder.hpp b/system/embdrv/lc3_dec/Api/Lc3Decoder.hpp
deleted file mode 100644
index aec64fe933..0000000000
--- a/system/embdrv/lc3_dec/Api/Lc3Decoder.hpp
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * Lc3Decoder.hpp
- *
- * 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.
- */
-
-#ifndef API_LC3DECODER_HPP_
-#define API_LC3DECODER_HPP_
-
-#include <cstdint>
-#include <vector>
-
-#include "Lc3Config.hpp"
-
-/*
- * Forward declaration of the "internal" class DecoderTop, so
- * that the private vector of single channel decoders can be declared in
- * Lc3Decoder.
- */
-namespace Lc3Dec {
-class DecoderTop;
-}
-
-/*
- * The LC3 decoder interface is specified in
- * LC3 specification Sections 2.4 "Decoder interfaces" (dr09r07).
- *
- * Lc3Decoder is designed such that all specified features are provided.
- *
- * In contrast to the Lc3Encoder, even 24bit and 32bit decoded audio
- * data can be provided - however in one fix byte arrangement which will
- * not meet all meaningful options. Providing 24bit and 32bit decoded audio
- * data makes the API more complex but does not increase the needed
- * resources when basic 16bit/sample audio data is desired only.
- *
- * Instantiating Lc3Decoder implies providing a Lc3Config instance. A copy of
- * this instance is available as public const member so that all essential
- * session parameters can be obtained throughout the lifetime of the Lc3Decoder
- * instance.
- *
- * There is no possibility of changing Lc3Config within Lc3Decoder. When session
- * parameters have to be changed, the calling application has to create a new
- * instance of Lc3Decoder.
- *
- * Lc3 supports operation with variable encoded bitrate. It is possible to
- * change the bitrate from frame to frame, where for preciseness the parameter
- * is not given as bitrate directly but in terms of the byte_count per frame.
- * This parameter has to be in the range of 20 to 400 (see LC3 specification
- * Section 3.2.5 "Bit budget and bitrate"). LC3 specification Sections 2.4
- * "Decoder interfaces" specifies "byte_count_max" of the decoder to allow
- * pre-allocation of resources. This parameter is provided here for completeness
- * and used for verifying the byte_count value of individual frames only. The
- * needed memory has to be provided by the calling application anyway, so that
- * it is up to the application whether a pre-allocation of memory is useful.
- *
- */
-
-class Lc3Decoder {
- public:
- /*
- * Convenience constructor of Lc3Decoder with two simple parameter only.
- * Note that this constructor instantiated Lc3Config implicitly with
- * Lc3Decoder(Lc3Config(Fs,frameDuration, 1)) that means that this
- * constructor provides processing of one channel (mono) and 16bit/sample
- * PCM output only.
- *
- * Parameters:
- * Fs : Sampling frequency in Hz -> see Lc3Config.hpp for supported values
- *
- * frameDuration : frame duration of 10ms (default) or 7.5ms
- * -> see Lc3Config.hpp for more details
- */
- Lc3Decoder(uint16_t Fs, Lc3Config::FrameDuration frameDuration =
- Lc3Config::FrameDuration::d10ms);
-
- /*
- * General constructor of Lc3Decoder.
- *
- * Parameters:
- * lc3Config_ : instance of Lc3Config. See documentation of Lc3Config for
- * more details. Note: providing an invalid instance of Lc3Config will result
- * in skipping any processing later.
- * The provided instance of Lc3Config will be copied to the
- * public field "lc3Config" (see below).
- *
- * bits_per_audio_sample_dec_ : Bits per audio sample for the output PCM
- * signal. See LC3 specification Section 2.4 "Decoder interfaces" and
- * Section 3.2.3 "Bits per sample" for the general LC3 requirement to support
- * 16, 24 and 32 bit. Note: This parameter may differ from the encoder input
- * PCM setting "bits_per_audio_sample_enc".
- *
- * byte_count_max_dec_ : Maximum allowed payload byte_count for a single
- * channel. When using and allowing external rate control, the maximum byte
- * count for the session may be used to configure the
- * session buffers without a need to dynamically reallocate memory during the
- * session.
- *
- * datapoints : pointer to an instance of a class allowing to collect internal
- * data. Note: this feature is used and prepared for testing of the codec
- * implementation only. See general "Readme.txt"
- */
- Lc3Decoder(Lc3Config lc3Config_, uint8_t bits_per_audio_sample_dec_ = 16,
- uint16_t byte_count_max_dec_ = 400, void* datapoints = nullptr);
-
- // no default constructor supported
- Lc3Decoder() = delete;
-
- // Destructor
- virtual ~Lc3Decoder();
-
- /*
- * Configuration provided during instantiation accessible as public const
- * fields. Note: Lc3Config provides a getter to check whether the
- * configuration is valid.
- */
- const Lc3Config lc3Config;
- const uint8_t bits_per_audio_sample_dec;
- const uint16_t byte_count_max_dec;
-
- // encoding error (see return values of "run" methods)
- static const uint8_t ERROR_FREE = 0x00;
- static const uint8_t INVALID_CONFIGURATION = 0x01;
- static const uint8_t INVALID_BYTE_COUNT = 0x02;
- static const uint8_t INVALID_X_OUT_SIZE = 0x03;
- static const uint8_t INVALID_BITS_PER_AUDIO_SAMPLE = 0x04;
- static const uint8_t DECODER_ALLOCATION_ERROR = 0x05;
-
- /*
- * Decoding one 16 bit/sample output frame for one channel
- *
- * Note that this methods returns the error INVALID_BITS_PER_AUDIO_SAMPLE
- * when the session has been configured for any bits_per_audio_sample_dec
- * != 16.
- *
- * Further, note that this method can be used for multi-channel configurations
- * as well, particularly when the provided multi-channel "run" (see below) is
- * not supporting the kind of byte stream concatenation existing in the
- * calling application.
- *
- * Parameters:
- * bytes : pointer to byte array holding the input LC3 encoded byte stream
- * of the given channel.
- * The size of this memory is given by the byte_count parameter.
- *
- * byte_count : number of encoded bytes; byte count to be used for decoding
- * the received frame payload.
- * Supported values are 20 bytes to byte_count_max_dec bytes.
- *
- * BFI : Bad Frame Indication flags
- * "0" signifies that no bit errors where detected in given "bytes"
- * "1" signifies a corrupt payload packet was detected in given
- * "bytes"
- *
- * x_out : pointer to output PCM data (16 bit/sample), where the memory
- * has to be provided by the calling application.
- *
- * x_out_size : number of 16 bit values supported by x_out
- * Note: this parameter has been introduced for clarity and
- * verification purpose only. The method will return
- * the error INVALID_X_OUT_SIZE when x_out_size !=
- * lc3Config.NF.
- *
- * BEC_detect : flag indication bit errors detected during decoding of input
- * bytes Note: a basic packet loss concealment (PLC) will be applied when
- * BEC_detect!=0, so that the returned audio data stays
- * somewhat acceptable.
- *
- * channelNr : index of channel to be processed (default=0), where channelNr
- * < lc3Config.Nc
- *
- *
- * Return value: error code as listed above.
- */
- uint8_t run(const uint8_t* bytes, uint16_t byte_count, uint8_t BFI,
- int16_t* x_out, uint16_t x_out_size, uint8_t& BEC_detect,
- uint8_t channelNr = 0);
-
- /*
- * Decoding one 16, 24, or 32 bit/sample output frame for one channel
- *
- * Note that every output PCM sample will need one 32 bit memory place in the
- * output stream independently from the configured bits_per_audio_sample_dec.
- *
- * Further, note that this method can be used for multi-channel configurations
- * as well, particularly when the provided multi-channel "run" (see below) is
- * not supporting the kind of byte stream concatenation existing in the
- * calling application.
- *
- * Parameters:
- * bytes : pointer to byte array holding the input LC3 encoded byte stream
- * of the given channel.
- * The size of this memory is given by the byte_count parameter.
- *
- * byte_count : number of encoded bytes; byte count to be used for decoding
- * the received frame payload.
- * Supported values are 20 bytes to byte_count_max_dec bytes.
- *
- * BFI : Bad Frame Indication flags
- * "0" signifies that no bit errors where detected in given "bytes"
- * "1" signifies a corrupt payload packet was detected in given
- * "bytes"
- *
- * x_out : pointer to output PCM data (memory 32 bit/sample, precision 16
- * bit/sample, 24 bit/sample or 32 bit/sample), where the memory has to be
- * provided by the calling application.
- *
- * x_out_size : number of 32 bit values supported by x_out
- * Note: this parameter has been introduced for clarity and
- * verification purpose only. The method will return
- * the error INVALID_X_OUT_SIZE when x_out_size !=
- * lc3Config.NF.
- *
- * BEC_detect : flag indication bit errors detected during decoding of input
- * bytes Note: a basic packet loss concealment (PLC) will be applied when
- * BEC_detect!=0, so that the returned audio data stays
- * somewhat acceptable.
- *
- * channelNr : index of channel to be processed (default=0), where channelNr
- * < lc3Config.Nc
- *
- *
- * Return value: error code as listed above.
- */
- uint8_t run(const uint8_t* bytes, uint16_t byte_count, uint8_t BFI,
- int32_t* x_out, uint16_t x_out_size, uint8_t& BEC_detect,
- uint8_t channelNr = 0);
-
- /*
- * Decoding one 16 bit/sample output frame for multiple channels.
- *
- * Note that this methods returns the error INVALID_BITS_PER_AUDIO_SAMPLE
- * when the session has been configured for any bits_per_audio_sample_dec
- * != 16.
- *
- * Parameters:
- * bytes : pointer to byte array holding the input LC3 encoded byte stream
- * of all given channels.
- * The size of this memory is given by the sum of all
- * byte_count_per_channel values (see parameter byte_count_per_channel). Note
- * that the encoded values of all channels are expected to be concatenated
- * without any stuffing bytes of meta data in between.
- *
- * byte_count_per_channel : number of encoded bytes; byte count to be used
- * for decoding the received frame payload per channel. Thus,
- * byte_count_per_channel is an array of byte_count values with length
- * lc3Conig.Nc Supported values are 20 bytes to byte_count_max_dec bytes per
- * channel.
- *
- * BFI_per_channel : lc3Conig.Nc length array of Bad Frame Indication flags
- * "0" signifies that no bit errors where detected in
- * given "bytes" "1" signifies a corrupt payload packet was detected in given
- * "bytes"
- *
- * x_out : pointer to output 16 bit/sample PCM data, where the memory
- * has to be provided by the calling application.
- *
- * x_out_size : number of 16 bit values supported by x_out
- * Note: this parameter has been introduced for clarity and
- * verification purpose only. The method will return
- * the error INVALID_X_OUT_SIZE when x_out_size !=
- * lc3Config.NF * lc3Conig.Nc.
- *
- * BEC_detect_per_channel : lc3Conig.Nc length array of flags indicating bit
- * errors detected during decoding of input bytes of a certain channel. Note:
- * a basic packet loss concealment (PLC) will be applied when BEC_detect!=0,
- * so that the returned audio data stays somewhat acceptable.
- *
- *
- * Return value: error code via "or" concatenation of the error codes of
- * processing the individual channels. Note: this "or" concatenation make
- * specific error diagnosis impossible. Thus only checking != ERROR_FREE is
- * meaningful. When more specific information is needed, the single channel
- * call (see above) need to be called.
- */
- uint8_t run(const uint8_t* bytes, const uint16_t* byte_count_per_channel,
- const uint8_t* BFI_per_channel, int16_t* x_out,
- uint32_t x_out_size, uint8_t* BEC_detect_per_channel);
-
- /*
- * Decoding one 16, 24, or 32 bit/sample output frame for multiple channels
- *
- * Note that every output PCM sample will need one 32 bit memory place in the
- * output stream independently from the configured bits_per_audio_sample_dec.
- *
- * Parameters:
- * bytes : pointer to byte array holding the input LC3 encoded byte stream
- * of all given channels.
- * The size of this memory is given by the sum of all
- * byte_count_per_channel values (see parameter byte_count_per_channel). Note
- * that the encoded values of all channels are expected to be concatenated
- * without any stuffing bytes of meta data in between.
- *
- * byte_count_per_channel : number of encoded bytes; byte count to be used
- * for decoding the received frame payload per channel. Thus,
- * byte_count_per_channel is an array of byte_count values with length
- * lc3Conig.Nc Supported values are 20 bytes to byte_count_max_dec bytes per
- * channel.
- *
- * BFI_per_channel : lc3Conig.Nc length array of Bad Frame Indication flags
- * "0" signifies that no bit errors where detected in
- * given "bytes" "1" signifies a corrupt payload packet was detected in given
- * "bytes"
- *
- * x_out : pointer to output 16, 24, or 32 bit/sample PCM data, where the
- * memory has to be provided by the calling application.
- *
- * x_out_size : number of 32 bit values supported by x_out
- * Note: this parameter has been introduced for clarity and
- * verification purpose only. The method will return
- * the error INVALID_X_OUT_SIZE when x_out_size !=
- * lc3Config.NF * lc3Conig.Nc.
- *
- * BEC_detect_per_channel : lc3Conig.Nc length array of flags indicating bit
- * errors detected during decoding of input bytes of a certain channel. Note:
- * a basic packet loss concealment (PLC) will be applied when BEC_detect!=0,
- * so that the returned audio data stays somewhat acceptable.
- *
- *
- * Return value: error code via "or" concatenation of the error codes of
- * processing the individual channels. Note: this "or" concatenation make
- * specific error diagnosis impossible. Thus only checking != ERROR_FREE is
- * meaningful. When more specific information is needed, the single channel
- * call (see above) need to be called.
- */
- uint8_t run(const uint8_t* bytes, const uint16_t* byte_count_per_channel,
- const uint8_t* BFI_per_channel, int32_t* x_out,
- uint32_t x_out_size, uint8_t* BEC_detect_per_channel);
-
- private:
- std::vector<Lc3Dec::DecoderTop*> decoderList;
-};
-
-#endif /* API_LC3DECODER_HPP_ */
diff --git a/system/embdrv/lc3_dec/Common/DctIV.cpp b/system/embdrv/lc3_dec/Common/DctIV.cpp
deleted file mode 100644
index 798322e57f..0000000000
--- a/system/embdrv/lc3_dec/Common/DctIV.cpp
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * DctIV.cpp
- *
- * 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 "DctIV.hpp"
-
-#include <cmath>
-
-/*
- * Notes on the choice of the applied FFT library:
- * - Different fast transform implementations for the DCT-IV can be selected
- * via USE_FFTW USE_FFTW_FOR_FFT // assume NF being 4 times an integer
- * USE_KISSFFT // assume NF being 4 times an integer
- * where only one of them is meaningful to be defined
- *
- * - Defining none of the fast transforms will lead to a direct implementation
- * which is good for testing but usually to slow for practial applications
- *
- * - USE_FFTW: The free "fftw" library should be fastest, but may be more
- * complicated to be build for embedded target devices. It provides dedicated
- * optimization for the DCT-IV and thus is preferred from a technical
- * perspective. In terms of licences "fftw" is free in the sense of GPL, which
- * is not liked in some products. There might be the option to ask the authors
- * for other licences (which they propose). Nevertheless, the "license" issue
- * has driven us to not bundle "fftw" directly with the LC3 implementation,
- * although the API for using it is provided and tested.
- *
- * - USE_FFTW_FOR_FFT: this is a not fully optimized alternative approach using
- * the complex fft provided by "fftw" instead of the dedicated optimized DCT-IV
- * implementation. This option is mainly provided to demonstrate the transition
- * from USE_FFTW to USE_KISSFFT
- *
- * - USE_KISSFFT: the free "kissfft" library is sligthly slower than "fftw",
- * but gives a majority of the possible performance gain over a "stupid" direct
- * DCT-IV implementation. "kissfft" does not provide a dedicated optimization
- * for DCT-IV so that some additional code for implementing a DCT-IV by a
- * complex fft has to be added. This also implies additional memory needed. The
- * big advantage of the "kissfft" is that it is less restrictive in terms of its
- * license. Further, the template based C++ implementation reduces its impact on
- * the build system to a minimum (we just need to include the right header
- * without needing to compile and link a separate file).
- *
- * - USE_KISSFFT is defined below to be the default choice. The other
- * alternatives may be selecting by providing its define via the compiler switch
- * -D<define>
- *
- * - The impact of the defines is restricted to this *.cpp file for clarity
- * reasons. Ok, to make this work, we needed a few "ugly" pointer casts, but we
- * really wanted to make sure, that no other code or build impact is generated
- * by the options in this file.
- */
-#define USE_OWN_FFT
-
-#if defined USE_FFTW || defined USE_FFTW_FOR_FFT
-#include <fftw3.h>
-
-#elif defined USE_KISSFFT
-#include "kissfft.hh"
-
-class KissfftConfig {
- public:
- KissfftConfig(uint16_t N) : inbuf(nullptr), outbuf(nullptr), fft(nullptr) {
- inbuf = new std::complex<double>[N];
- outbuf = new std::complex<double>[N];
- twiddle = new std::complex<double>[N];
- fft = new kissfft<double>(N, false);
-
- const double pi = std::acos(-1);
- for (uint16_t n = 0; n < N; n++) {
- twiddle[n] =
- std::complex<double>(std::cos(-pi * (8 * n + 1) / (8.0 * N * 2)),
- std::sin(-pi * (8 * n + 1) / (8.0 * N * 2)));
- }
- }
-
- ~KissfftConfig() {
- if (nullptr != fft) {
- delete fft;
- }
- if (nullptr != inbuf) {
- delete[] inbuf;
- }
- if (nullptr != outbuf) {
- delete[] outbuf;
- }
- if (nullptr != twiddle) {
- delete[] twiddle;
- }
- }
-
- void transform() {
- if (nullptr != fft) {
- fft->transform(inbuf, outbuf);
- }
- }
-
- std::complex<double>* inbuf;
- std::complex<double>* outbuf;
- std::complex<double>* twiddle;
- kissfft<double>* fft;
-};
-
-#elif defined USE_OWN_FFT
-#include <complex>
-
-#include "fft.h"
-#endif
-
-DctIVDbl::DctIVDbl(uint16_t NF_)
- : NF(NF_), in(nullptr), out(nullptr), dctIVconfig(nullptr) {
- in = new double[NF];
- out = new double[NF];
-
-#if defined USE_FFTW
- dctIVconfig = fftw_plan_r2r_1d(NF, in, out, FFTW_REDFT11, FFTW_ESTIMATE);
-
-#elif defined USE_FFTW_FOR_FFT
- dctIVconfig = fftw_plan_dft_1d(NF / 2, reinterpret_cast<fftw_complex*>(in),
- reinterpret_cast<fftw_complex*>(out),
- FFTW_FORWARD, FFTW_ESTIMATE);
-
-#elif defined USE_KISSFFT
- dctIVconfig = new KissfftConfig(NF / 2);
-
-#elif defined USE_OWN_FFT
-
- int N = NF / 2;
- std::complex<double>* twiddle = new std::complex<double>[N];
- dctIVconfig = twiddle;
- const double pi = std::acos(-1);
- for (uint16_t n = 0; n < N; n++) {
- twiddle[n] =
- std::complex<double>(std::cos(-pi * (8 * n + 1) / (8.0 * N * 2)),
- std::sin(-pi * (8 * n + 1) / (8.0 * N * 2)));
- }
-
-#endif
-
- for (uint16_t n = 0; n < NF; n++) {
- in[n] = 0;
- out[n] = 0;
- }
-}
-
-DctIVDbl::~DctIVDbl() {
-#if defined USE_FFTW || defined USE_FFTW_FOR_FFT
- if (nullptr != dctIVconfig) {
- fftw_destroy_plan(reinterpret_cast<fftw_plan>(dctIVconfig));
- }
-
-#elif defined USE_KISSFFT
- if (nullptr != dctIVconfig) {
- KissfftConfig* kissfftConfig =
- reinterpret_cast<KissfftConfig*>(dctIVconfig);
- delete kissfftConfig;
- }
-
-#elif defined USE_OWN_FFT
- std::complex<double>* twiddle = (std::complex<double>*)dctIVconfig;
- delete[] twiddle;
-
-#endif
- if (nullptr != in) {
- delete[] in;
- }
- if (nullptr != out) {
- delete[] out;
- }
-}
-
-void DctIVDirectDbl(uint16_t N, const double* const tw, double* const X) {
- const double pi = std::acos(-1);
- for (uint16_t k = 0; k < N; k++) {
- X[k] = 0;
- for (uint16_t n = 0; n < N; n++) {
- X[k] += tw[n] * std::cos(pi / N * (n + 0.5) * (k + 0.5));
- }
- X[k] *= 2;
- }
-}
-
-void DctIVDbl::run() {
-#ifdef USE_FFTW
- fftw_execute(reinterpret_cast<fftw_plan>(dctIVconfig));
-
-#elif defined USE_FFTW_FOR_FFT
- const double pi = std::acos(-1);
- // assume NF being 4 times an integer
- for (uint16_t n = 1; n < NF / 2; n += 2) {
- double buffer;
- buffer = in[n];
- in[n] = in[NF - n];
- in[NF - n] = buffer;
- }
- for (uint16_t n = 0; n < NF; n += 2) {
- double real = in[n + 0];
- double imag = in[n + 1];
- in[n + 0] = real * std::cos(-pi * (4 * n + 1) / (8.0 * NF)) -
- imag * std::sin(-pi * (4 * n + 1) / (8.0 * NF));
- in[n + 1] = real * std::sin(-pi * (4 * n + 1) / (8.0 * NF)) +
- imag * std::cos(-pi * (4 * n + 1) / (8.0 * NF));
- }
-
- fftw_execute(reinterpret_cast<fftw_plan>(dctIVconfig));
-
- for (uint16_t n = 0; n < NF; n += 2) {
- double real = out[n + 0];
- double imag = out[n + 1];
- out[n + 0] = 2 * (real * std::cos(-pi * (4 * n + 1) / (8.0 * NF)) -
- imag * std::sin(-pi * (4 * n + 1) / (8.0 * NF)));
- out[n + 1] = 2 * (real * std::sin(-pi * (4 * n + 1) / (8.0 * NF)) +
- imag * std::cos(-pi * (4 * n + 1) / (8.0 * NF)));
- }
- for (uint16_t n = 1; n < NF / 2; n += 2) {
- double buffer;
- buffer = out[n];
- out[n] = -out[NF - n];
- out[NF - n] = -buffer;
- }
-
-#elif defined USE_KISSFFT
- // assume NF being 4 times an integer
- KissfftConfig* kissfftConfig = reinterpret_cast<KissfftConfig*>(dctIVconfig);
- for (uint16_t n = 0; n < NF / 2; n++) {
- kissfftConfig->inbuf[n] =
- kissfftConfig->twiddle[n] *
- std::complex<double>(in[2 * n], in[NF - 2 * n - 1]);
- }
-
- kissfftConfig->transform();
-
- for (uint16_t n = 0; n < NF / 2; n++) {
- std::complex<double> complexOut =
- kissfftConfig->twiddle[n] * kissfftConfig->outbuf[n];
- out[2 * n] = complexOut.real() * 2;
- out[NF - 2 * n - 1] = -complexOut.imag() * 2;
- }
-
-#elif defined USE_OWN_FFT
-
- fft_complex inbuf[NF / 2];
- fft_complex outbuf[NF / 2];
-
- // assume NF being 4 times an integer
- for (uint16_t n = 1; n < NF / 2; n += 2) {
- double buffer;
- buffer = in[n];
- in[n] = in[NF - n];
- in[NF - n] = buffer;
- }
-
- std::complex<double>* twiddle = (std::complex<double>*)dctIVconfig;
- for (uint16_t n = 0; n < NF / 2; n++) {
- double real = in[2 * n + 0];
- double imag = in[2 * n + 1];
- in[2 * n + 0] = real * twiddle[n].real() - imag * twiddle[n].imag();
- in[2 * n + 1] = real * twiddle[n].imag() + imag * twiddle[n].real();
- }
-
- for (uint16_t n = 0; n < NF / 2; n++) {
- inbuf[n].re = in[2 * n];
- inbuf[n].im = in[2 * n + 1];
- }
-
- fft_complex* actal_output = fft(false, inbuf, NF / 2, inbuf, outbuf);
-
- for (uint16_t n = 0; n < NF / 2; n++) {
- double real = actal_output[n].re;
- double imag = actal_output[n].im;
- out[2 * n + 0] = 2 * (real * twiddle[n].real() - imag * twiddle[n].imag());
- out[2 * n + 1] = 2 * (real * twiddle[n].imag() + imag * twiddle[n].real());
- }
-
- for (uint16_t n = 1; n < NF / 2; n += 2) {
- double buffer;
- buffer = out[n];
- out[n] = -out[NF - n];
- out[NF - n] = -buffer;
- }
-
-#else
- DctIVDirectDbl(NF, in, out);
-#endif
-}
diff --git a/system/embdrv/lc3_dec/Common/DctIV.hpp b/system/embdrv/lc3_dec/Common/DctIV.hpp
deleted file mode 100644
index 1e40d23f9d..0000000000
--- a/system/embdrv/lc3_dec/Common/DctIV.hpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * DctIV.hpp
- *
- * 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.
- */
-
-#ifndef DCT_IV_H_
-#define DCT_IV_H_
-
-#include <cstdint>
-
-class DctIVDbl {
- public:
- DctIVDbl(uint16_t NF_);
- virtual ~DctIVDbl();
-
- void run();
-
- const uint16_t NF;
- double* in;
- double* out;
- void* dctIVconfig;
-};
-
-#endif // DCT_IV_H_
diff --git a/system/embdrv/lc3_dec/Common/Lc3Config.cpp b/system/embdrv/lc3_dec/Common/Lc3Config.cpp
deleted file mode 100644
index 1d58b04f8e..0000000000
--- a/system/embdrv/lc3_dec/Common/Lc3Config.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Lc3Config.cpp
- *
- * 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 "Lc3Config.hpp"
-
-#include <cmath>
-
-Lc3Config::Lc3Config(uint16_t Fs_, FrameDuration N_ms_, uint8_t Nc_)
- : errorStatus(ERROR_FREE),
- Fs(Fs_),
- Fs_ind(getFs_ind(Fs)),
- N_ms(N_ms_),
- NF(getNF(Fs, N_ms_)),
- NE(getNE(NF, N_ms_)),
- Z((N_ms == FrameDuration::d10ms) ? 3 * NF / 8 : 7 * NF / 30),
- Nc(Nc_),
- N_b(((N_ms == Lc3Config::FrameDuration::d7p5ms) && (Fs == 8000)) ? 60
- : 64) {
- if (0 == Nc) // we do not restrict the maximum yet (naturally limited to 255
- // because of the chosen datatype)
- {
- errorStatus |= INVALID_NUMBER_OF_CHANNELS;
- }
-}
-
-Lc3Config::~Lc3Config() {}
-
-bool Lc3Config::isValid() const { return ERROR_FREE == errorStatus; }
-
-uint8_t Lc3Config::getErrorStatus() const { return errorStatus; }
-
-uint8_t Lc3Config::getFs_ind(uint16_t Fs) {
- uint8_t fs_ind = 0;
- switch (Fs) {
- case 8000:
- fs_ind = 0;
- break;
- case 16000:
- fs_ind = 1;
- break;
- case 24000:
- fs_ind = 2;
- break;
- case 32000:
- fs_ind = 3;
- break;
- case 44100:;
- case 48000:
- fs_ind = 4;
- break;
- default:
- errorStatus |= INVALID_SAMPLING_RATE;
- }
- return fs_ind;
-}
-
-uint16_t Lc3Config::getNF(uint16_t Fs, FrameDuration N_ms) {
- uint16_t NF = 80;
- if (FrameDuration::d10ms == N_ms) {
- switch (Fs) {
- case 8000:
- NF = 80;
- break;
- case 16000:
- NF = 160;
- break;
- case 24000:
- NF = 240;
- break;
- case 32000:
- NF = 320;
- break;
- case 44100:;
- case 48000:
- NF = 480;
- break;
- default:
- errorStatus |= INVALID_SAMPLING_RATE;
- }
- } else if (FrameDuration::d7p5ms == N_ms) {
- switch (Fs) {
- case 8000:
- NF = 60;
- break;
- case 16000:
- NF = 120;
- break;
- case 24000:
- NF = 180;
- break;
- case 32000:
- NF = 240;
- break;
- case 44100:;
- case 48000:
- NF = 360;
- break;
- default:
- errorStatus |= INVALID_SAMPLING_RATE;
- }
- } else {
- // We never should reach this line unless
- // strange things happen. However, we want
- // to be on the safe side and thus handle
- // this case explicitly.
- errorStatus |= INVALID_FRAME_DURATION;
- }
- return NF;
-}
-
-uint16_t Lc3Config::getNE(uint16_t NF, FrameDuration N_ms) {
- // 3.3.4.3 Time-Frequency Transformation (d09r04_*implementorComments*)
- if (FrameDuration::d10ms == N_ms) {
- return (480 == NF) ? 400 : NF;
- } else {
- return (360 == NF) ? 300 : NF;
- }
-}
-
-uint16_t Lc3Config::getByteCountFromBitrate(uint32_t bitrate) const {
- // Section 3.2.5 Bit budget and bitrate (LC3_Specification_d09r06)
- double f_scal = getFscal();
- double N_ms_value = getNmsValue();
- return floor((bitrate * N_ms_value * f_scal) / 8000.0);
-}
-
-uint32_t Lc3Config::getBitrateFromByteCount(uint16_t nbytes) const {
- // Section 3.2.5 Bit budget and bitrate (LC3_Specification_d1.0r03)
- // Notes:
- // - this implementation includes Errata 15051
- // - this utility function is not used within the LC3 code so far, but
- // provided here for completeness
- double f_scal = getFscal();
- double N_ms_value = getNmsValue();
- return ceil((8000.0 * nbytes) / (N_ms_value * f_scal));
-}
-
-double Lc3Config::getFscal() const {
- // Section 3.2.2 Sampling rates (LC3_Specification_d1.0r03)
- return (44100 == Fs) ? 48000.0 / 44100.0 : 1.0;
-}
-
-double Lc3Config::getNmsValue() const {
- return (FrameDuration::d10ms == N_ms) ? 10.0 : 7.5;
-}
diff --git a/system/embdrv/lc3_dec/Common/Tables/BandIndexTables.cpp b/system/embdrv/lc3_dec/Common/Tables/BandIndexTables.cpp
deleted file mode 100644
index 26bc3ba513..0000000000
--- a/system/embdrv/lc3_dec/Common/Tables/BandIndexTables.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * BandIndexTables.cpp
- *
- * 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.
- */
-
-// LC3 Specification d09r01.pdf
-// Section 5.7.1 Band Tables Index I_fs
-#include "BandIndexTables.hpp"
-
-// LC3 Specification d09r01.pdf; Page 86 of 177
-// LC3 Specification Section 3.7.2 (d09r04_*implementorComments*)
-// Page 115 of 256
-// Band tables index I_fs for 10 ms frame duration
-int I_8000[65] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
- 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
- 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 51, 53,
- 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 80};
-int I_16000[65] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
- 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
- 22, 23, 24, 25, 26, 27, 28, 30, 32, 34, 36,
- 38, 40, 42, 44, 46, 48, 50, 52, 55, 58, 61,
- 64, 67, 70, 73, 76, 80, 84, 88, 92, 96, 101,
- 106, 111, 116, 121, 127, 133, 139, 146, 153, 160};
-int I_24000[65] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
- 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
- 22, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41,
- 43, 46, 49, 52, 55, 58, 61, 64, 68, 72, 76,
- 80, 85, 90, 95, 100, 106, 112, 118, 125, 132, 139,
- 147, 155, 164, 173, 183, 193, 204, 215, 227, 240};
-int I_32000[65] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
- 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22,
- 24, 26, 28, 30, 32, 34, 36, 38, 41, 44, 47,
- 50, 53, 56, 60, 64, 68, 72, 76, 81, 86, 91,
- 97, 103, 109, 116, 123, 131, 139, 148, 157, 166, 176,
- 187, 199, 211, 224, 238, 252, 268, 284, 302, 320};
-int I_48000[65] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
- 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24,
- 26, 28, 30, 32, 34, 36, 39, 42, 45, 48, 51,
- 55, 59, 63, 67, 71, 76, 81, 86, 92, 98, 105,
- 112, 119, 127, 135, 144, 154, 164, 175, 186, 198, 211,
- 225, 240, 256, 273, 291, 310, 330, 352, 375, 400};
-
-// LC3 Specification Section 3.7.2 (d09r04_*implementorComments*)
-// Page 115/116 of 256
-// Band tables index I_fs for 7.5 ms frame duration
-int I_8000_7p5ms[61] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
- 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
- 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
- 52, 53, 54, 55, 56, 57, 58, 59, 60};
-int I_16000_7p5ms[65] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
- 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 65, 68,
- 71, 74, 77, 80, 83, 86, 90, 94, 98, 102, 106, 110, 115, 120};
-int I_24000_7p5ms[65] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
- 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
- 22, 23, 24, 25, 26, 27, 29, 31, 33, 35, 37,
- 39, 41, 43, 45, 47, 49, 52, 55, 58, 61, 64,
- 67, 70, 74, 78, 82, 86, 90, 95, 100, 105, 110,
- 115, 121, 127, 134, 141, 148, 155, 163, 171, 180};
-int I_32000_7p5ms[65] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
- 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
- 22, 23, 24, 26, 28, 30, 32, 34, 36, 38, 40,
- 42, 45, 48, 51, 54, 57, 60, 63, 67, 71, 75,
- 79, 84, 89, 94, 99, 105, 111, 117, 124, 131, 138,
- 146, 154, 163, 172, 182, 192, 203, 215, 227, 240};
-int I_48000_7p5ms[65] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
- 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
- 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 43,
- 46, 49, 52, 55, 59, 63, 67, 71, 75, 80, 85,
- 90, 96, 102, 108, 115, 122, 129, 137, 146, 155, 165,
- 175, 186, 197, 209, 222, 236, 251, 266, 283, 300};
diff --git a/system/embdrv/lc3_dec/Common/Tables/BandIndexTables.hpp b/system/embdrv/lc3_dec/Common/Tables/BandIndexTables.hpp
deleted file mode 100644
index dfe7734d58..0000000000
--- a/system/embdrv/lc3_dec/Common/Tables/BandIndexTables.hpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * BandIndexTables.hpp
- *
- * 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.
- */
-
-#ifndef BAND_INDEX_TABLES_H_
-#define BAND_INDEX_TABLES_H_
-
-// LC3 Specification d09r01.pdf
-// Section 5.7.1 Band Tables Index I_fs
-
-// LC3 Specification d09r04_*implementorComments*
-// Section 3.7.1 Band tables index I_fs for 10 ms frame duration
-
-extern int I_8000[65];
-extern int I_16000[65];
-extern int I_24000[65];
-extern int I_32000[65];
-extern int I_48000[65];
-
-// LC3 Specification d09r04_*implementorComments*
-// Section 3.7.2 Band tables index I_fs for 7.5 ms frame duration
-
-extern int I_8000_7p5ms[61];
-extern int I_16000_7p5ms[65];
-extern int I_24000_7p5ms[65];
-extern int I_32000_7p5ms[65];
-extern int I_48000_7p5ms[65];
-
-#endif // BAND_INDEX_TABLES_H_
diff --git a/system/embdrv/lc3_dec/Common/Tables/LongTermPostfilterCoefficients.cpp b/system/embdrv/lc3_dec/Common/Tables/LongTermPostfilterCoefficients.cpp
deleted file mode 100644
index 340ae20022..0000000000
--- a/system/embdrv/lc3_dec/Common/Tables/LongTermPostfilterCoefficients.cpp
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * LongTermPostfilterCoefficients.cpp
- *
- * 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.
- */
-
-// LC3 Specification d09r01.pdf
-// Section 5.7.5 Long Term Postfiltering
-#include "LongTermPostfilterCoefficients.hpp"
-
-// LC3 Specification d09r01.pdf; Page 110 of 177
-double tab_resamp_filter[239] = {
- -2.043055832879108e-05, -4.463458936757081e-05, -7.163663994481459e-05,
- -1.001011132655914e-04, -1.283728480660395e-04, -1.545438297704662e-04,
- -1.765445671257668e-04, -1.922569599584802e-04, -1.996438192500382e-04,
- -1.968886856400547e-04, -1.825383318834690e-04, -1.556394266046803e-04,
- -1.158603651792638e-04, -6.358930335348977e-05, +2.810064795067786e-19,
- +7.292180213001337e-05, +1.523970757644272e-04, +2.349207769898906e-04,
- +3.163786496265269e-04, +3.922117380894736e-04, +4.576238491064392e-04,
- +5.078242936704864e-04, +5.382955231045915e-04, +5.450729176175875e-04,
- +5.250221548270982e-04, +4.760984242947349e-04, +3.975713799264791e-04,
- +2.902002172907180e-04, +1.563446669975615e-04, -5.818801416923580e-19,
- -1.732527127898052e-04, -3.563859653300760e-04, -5.411552308801147e-04,
- -7.184140229675020e-04, -8.785052315963854e-04, -1.011714513697282e-03,
- -1.108767055632304e-03, -1.161345220483996e-03, -1.162601694464620e-03,
- -1.107640974148221e-03, -9.939415631563015e-04, -8.216921898513225e-04,
- // LC3 Specification d09r01.pdf; Page 111 of 177
- -5.940177657925908e-04, -3.170746535382728e-04, +9.746950818779534e-19,
- +3.452937604228947e-04, +7.044808705458705e-04, +1.061334465662964e-03,
- +1.398374734488549e-03, +1.697630799350524e-03, +1.941486748731660e-03,
- +2.113575906669355e-03, +2.199682452179964e-03, +2.188606246517629e-03,
- +2.072945458973295e-03, +1.849752491313908e-03, +1.521021876908738e-03,
- +1.093974255016849e-03, +5.811080624426164e-04, -1.422482656398999e-18,
- -6.271537303228204e-04, -1.274251404913447e-03, -1.912238389850182e-03,
- -2.510269249380764e-03, -3.037038298629825e-03, -3.462226871101535e-03,
- -3.758006719596473e-03, -3.900532466948409e-03, -3.871352309895838e-03,
- -3.658665583679722e-03, -3.258358512646846e-03, -2.674755551508349e-03,
- -1.921033054368456e-03, -1.019254326838640e-03, +1.869623690895593e-18,
- +1.098415446732263e-03, +2.231131973532823e-03, +3.348309272768835e-03,
- +4.397022774386510e-03, +5.323426722644900e-03, +6.075105310368700e-03,
- +6.603520247552113e-03, +6.866453987193027e-03, +6.830342695906946e-03,
- +6.472392343549424e-03, +5.782375213956374e-03, +4.764012726389739e-03,
- +3.435863514113467e-03, +1.831652835406657e-03, -2.251898372838663e-18,
- -1.996476188279370e-03, -4.082668858919100e-03, -6.173080374929424e-03,
- -8.174448945974208e-03, -9.988823864332691e-03, -1.151698705819990e-02,
- -1.266210056063963e-02, -1.333344579518481e-02, -1.345011199343934e-02,
- -1.294448809639154e-02, -1.176541543002924e-02, -9.880867320401294e-03,
- -7.280036402392082e-03, -3.974730209151807e-03, +2.509617777250391e-18,
- +4.586044219717467e-03, +9.703248998383679e-03, +1.525124770818010e-02,
- +2.111205854013017e-02, +2.715337236094137e-02, +3.323242450843114e-02,
- +3.920032029020130e-02, +4.490666443426786e-02, +5.020433088017846e-02,
- +5.495420172681558e-02, +5.902970324375908e-02, +6.232097270672976e-02,
- +6.473850225260731e-02, +6.621612450840858e-02, +6.671322871619612e-02,
- +6.621612450840858e-02, +6.473850225260731e-02, +6.232097270672976e-02,
- +5.902970324375908e-02, +5.495420172681558e-02, +5.020433088017846e-02,
- +4.490666443426786e-02, +3.920032029020130e-02, +3.323242450843114e-02,
- +2.715337236094137e-02, +2.111205854013017e-02, +1.525124770818010e-02,
- +9.703248998383679e-03, +4.586044219717467e-03, +2.509617777250391e-18,
- -3.974730209151807e-03, -7.280036402392082e-03, -9.880867320401294e-03,
- -1.176541543002924e-02, -1.294448809639154e-02, -1.345011199343934e-02,
- -1.333344579518481e-02, -1.266210056063963e-02, -1.151698705819990e-02,
- -9.988823864332691e-03, -8.174448945974208e-03, -6.173080374929424e-03,
- -4.082668858919100e-03, -1.996476188279370e-03, -2.251898372838663e-18,
- +1.831652835406657e-03, +3.435863514113467e-03, +4.764012726389739e-03,
- +5.782375213956374e-03, +6.472392343549424e-03, +6.830342695906946e-03,
- +6.866453987193027e-03, +6.603520247552113e-03, +6.075105310368700e-03,
- +5.323426722644900e-03, +4.397022774386510e-03, +3.348309272768835e-03,
- +2.231131973532823e-03, +1.098415446732263e-03, +1.869623690895593e-18,
- -1.019254326838640e-03, -1.921033054368456e-03, -2.674755551508349e-03,
- -3.258358512646846e-03, -3.658665583679722e-03, -3.871352309895838e-03,
- -3.900532466948409e-03, -3.758006719596473e-03, -3.462226871101535e-03,
- -3.037038298629825e-03, -2.510269249380764e-03, -1.912238389850182e-03,
- -1.274251404913447e-03, -6.271537303228204e-04, -1.422482656398999e-18,
- +5.811080624426164e-04, +1.093974255016849e-03, +1.521021876908738e-03,
- +1.849752491313908e-03, +2.072945458973295e-03, +2.188606246517629e-03,
- +2.199682452179964e-03, +2.113575906669355e-03, +1.941486748731660e-03,
- +1.697630799350524e-03, +1.398374734488549e-03, +1.061334465662964e-03,
- +7.044808705458705e-04, +3.452937604228947e-04, +9.746950818779534e-19,
- -3.170746535382728e-04, -5.940177657925908e-04, -8.216921898513225e-04,
- -9.939415631563015e-04, -1.107640974148221e-03, -1.162601694464620e-03,
- -1.161345220483996e-03, -1.108767055632304e-03, -1.011714513697282e-03,
- -8.785052315963854e-04, -7.184140229675020e-04, -5.411552308801147e-04,
- -3.563859653300760e-04, -1.732527127898052e-04, -5.818801416923580e-19,
- // LC3 Specification d09r01.pdf; Page 112 of 177
- +1.563446669975615e-04, +2.902002172907180e-04, +3.975713799264791e-04,
- +4.760984242947349e-04, +5.250221548270982e-04, +5.450729176175875e-04,
- +5.382955231045915e-04, +5.078242936704864e-04, +4.576238491064392e-04,
- +3.922117380894736e-04, +3.163786496265269e-04, +2.349207769898906e-04,
- +1.523970757644272e-04, +7.292180213001337e-05, +2.810064795067786e-19,
- -6.358930335348977e-05, -1.158603651792638e-04, -1.556394266046803e-04,
- -1.825383318834690e-04, -1.968886856400547e-04, -1.996438192500382e-04,
- -1.922569599584802e-04, -1.765445671257668e-04, -1.545438297704662e-04,
- -1.283728480660395e-04, -1.001011132655914e-04, -7.163663994481459e-05,
- -4.463458936757081e-05, -2.043055832879108e-05};
-double tab_ltpf_interp_R[31] = {
- -2.874561161519444e-03, -3.001251025861499e-03, +2.745471654059321e-03,
- +1.535727698935322e-02, +2.868234046665657e-02, +2.950385026557377e-02,
- +4.598334491135473e-03, -4.729632459043440e-02, -1.058359163062837e-01,
- -1.303050213607112e-01, -7.544046357555201e-02, +8.357885725250529e-02,
- +3.301825710764459e-01, +6.032970076366158e-01, +8.174886856243178e-01,
- +8.986382851273982e-01, +8.174886856243178e-01, +6.032970076366158e-01,
- +3.301825710764459e-01, +8.357885725250529e-02, -7.544046357555201e-02,
- -1.303050213607112e-01, -1.058359163062837e-01, -4.729632459043440e-02,
- +4.598334491135473e-03, +2.950385026557377e-02, +2.868234046665657e-02,
- +1.535727698935322e-02, +2.745471654059321e-03, -3.001251025861499e-03,
- -2.874561161519444e-03};
-double tab_ltpf_interp_x12k8[15] = {
- +6.698858366939680e-03, +3.967114782344967e-02, +1.069991860896389e-01,
- +2.098804630681809e-01, +3.356906254147840e-01, +4.592209296082350e-01,
- +5.500750019177116e-01, +5.835275754221211e-01, +5.500750019177116e-01,
- +4.592209296082350e-01, +3.356906254147840e-01, +2.098804630681809e-01,
- +1.069991860896389e-01, +3.967114782344967e-02, +6.698858366939680e-03};
-double tab_ltpf_num_8000[4][3] = {
- {6.023618207009578e-01, 4.197609261363617e-01, -1.883424527883687e-02},
- {5.994768582584314e-01, 4.197609261363620e-01, -1.594928283631041e-02},
- {5.967764663733787e-01, 4.197609261363617e-01, -1.324889095125780e-02},
- {5.942410120098895e-01, 4.197609261363618e-01, -1.071343658776831e-02}};
-double tab_ltpf_num_16000[4][3] = {
- {6.023618207009578e-01, 4.197609261363617e-01, -1.883424527883687e-02},
- {5.994768582584314e-01, 4.197609261363620e-01, -1.594928283631041e-02},
- {5.967764663733787e-01, 4.197609261363617e-01, -1.324889095125780e-02},
- {5.942410120098895e-01, 4.197609261363618e-01, -1.071343658776831e-02}};
-double tab_ltpf_num_24000[4][5] = {
- {3.989695588963494e-01, 5.142508607708275e-01, 1.004382966157454e-01,
- -1.278893956818042e-02, -1.572280075461383e-03},
- {3.948634911286333e-01, 5.123819208048688e-01, 1.043194926386267e-01,
- -1.091999960222166e-02, -1.347408330627317e-03},
- {3.909844475885914e-01, 5.106053522688359e-01, 1.079832524685944e-01,
- -9.143431066188848e-03, -1.132124620551895e-03},
- {3.873093888199928e-01, 5.089122083363975e-01, 1.114517380217371e-01,
- -7.450287133750717e-03, -9.255514050963111e-04}};
-double tab_ltpf_num_32000[4][7] = {
- // LC3 Specification d09r01.pdf; Page 113 of 177
- {2.982379446702096e-01, 4.652809203721290e-01, 2.105997428614279e-01,
- 3.766780380806063e-02, -1.015696155796564e-02, -2.535880996101096e-03,
- -3.182946168719958e-04},
- {2.943834154510240e-01, 4.619294002718798e-01, 2.129465770091844e-01,
- 4.066175002688857e-02, -8.693272297010050e-03, -2.178307114679820e-03,
- -2.742888063983188e-04},
- {2.907439213122688e-01, 4.587461910960279e-01, 2.151456974108970e-01,
- 4.350104772529774e-02, -7.295495347716925e-03, -1.834395637237086e-03,
- -2.316920186482416e-04},
- {2.872975852589158e-01, 4.557148886861379e-01, 2.172126950911401e-01,
- 4.620088878229615e-02, -5.957463802125952e-03, -1.502934284345198e-03,
- -1.903851911308866e-04}};
-double tab_ltpf_num_48000[4][11] = {
- {1.981363739883217e-01, 3.524494903964904e-01, 2.513695269649414e-01,
- 1.424146237314458e-01, 5.704731023952599e-02, 9.293366241586384e-03,
- -7.226025368953745e-03, -3.172679890356356e-03, -1.121835963567014e-03,
- -2.902957238400140e-04, -4.270815593769240e-05},
- {1.950709426598375e-01, 3.484660408341632e-01, 2.509988459466574e-01,
- 1.441167412482088e-01, 5.928947317677285e-02, 1.108923827452231e-02,
- -6.192908108653504e-03, -2.726705509251737e-03, -9.667125826217151e-04,
- -2.508100923165204e-04, -3.699938766131869e-05},
- {1.921810055196015e-01, 3.446945561091513e-01, 2.506220094626024e-01,
- 1.457102447664837e-01, 6.141132133664525e-02, 1.279941396562798e-02,
- -5.203721087886321e-03, -2.297324511109085e-03, -8.165608133217555e-04,
- -2.123855748277408e-04, -3.141271330981649e-05},
- {1.894485314175868e-01, 3.411139251108252e-01, 2.502406876894361e-01,
- 1.472065631098081e-01, 6.342477229539051e-02, 1.443203434150312e-02,
- -4.254449144657098e-03, -1.883081472613493e-03, -6.709619060722140e-04,
- -1.749363341966872e-04, -2.593864735284285e-05}};
-double tab_ltpf_den_8000[4][5] = {
- {0.000000000000000e+00, 2.098804630681809e-01, 5.835275754221211e-01,
- 2.098804630681809e-01, 0.000000000000000e+00},
- {0.000000000000000e+00, 1.069991860896389e-01, 5.500750019177116e-01,
- 3.356906254147840e-01, 6.698858366939680e-03},
- {0.000000000000000e+00, 3.967114782344967e-02, 4.592209296082350e-01,
- 4.592209296082350e-01, 3.967114782344967e-02},
- {0.000000000000000e+00, 6.698858366939680e-03, 3.356906254147840e-01,
- 5.500750019177116e-01, 1.069991860896389e-01}};
-double tab_ltpf_den_16000[4][5] = {
- {0.000000000000000e+00, 2.098804630681809e-01, 5.835275754221211e-01,
- 2.098804630681809e-01, 0.000000000000000e+00},
- {0.000000000000000e+00, 1.069991860896389e-01, 5.500750019177116e-01,
- 3.356906254147840e-01, 6.698858366939680e-03},
- {0.000000000000000e+00, 3.967114782344967e-02, 4.592209296082350e-01,
- 4.592209296082350e-01, 3.967114782344967e-02},
- {0.000000000000000e+00, 6.698858366939680e-03, 3.356906254147840e-01,
- 5.500750019177116e-01, 1.069991860896389e-01}};
-double tab_ltpf_den_24000[4][7] = {
- {0.000000000000000e+00, 6.322231627323796e-02, 2.507309606013235e-01,
- 3.713909428901578e-01, 2.507309606013235e-01, 6.322231627323796e-02,
- 0.000000000000000e+00},
- // LC3 Specification d09r01.pdf; Page 114 of 177
- {0.000000000000000e+00, 3.459272174099855e-02, 1.986515602645028e-01,
- 3.626411726581452e-01, 2.986750548992179e-01, 1.013092873505928e-01,
- 4.263543712369752e-03},
- {0.000000000000000e+00, 1.535746784963907e-02, 1.474344878058222e-01,
- 3.374259553990717e-01, 3.374259553990717e-01, 1.474344878058222e-01,
- 1.535746784963907e-02},
- {0.000000000000000e+00, 4.263543712369752e-03, 1.013092873505928e-01,
- 2.986750548992179e-01, 3.626411726581452e-01, 1.986515602645028e-01,
- 3.459272174099855e-02}};
-double tab_ltpf_den_32000[4][9] = {
- {0.000000000000000e+00, 2.900401878228730e-02, 1.129857420560927e-01,
- 2.212024028097570e-01, 2.723909472446145e-01, 2.212024028097570e-01,
- 1.129857420560927e-01, 2.900401878228730e-02, 0.000000000000000e+00},
- {0.000000000000000e+00, 1.703153418385261e-02, 8.722503785537784e-02,
- 1.961407762232199e-01, 2.689237982237257e-01, 2.424999102756389e-01,
- 1.405773364650031e-01, 4.474877169485788e-02, 3.127030243100724e-03},
- {0.000000000000000e+00, 8.563673748488349e-03, 6.426222944493845e-02,
- 1.687676705918012e-01, 2.587445937795505e-01, 2.587445937795505e-01,
- 1.687676705918012e-01, 6.426222944493845e-02, 8.563673748488349e-03},
- {0.000000000000000e+00, 3.127030243100724e-03, 4.474877169485788e-02,
- 1.405773364650031e-01, 2.424999102756389e-01, 2.689237982237257e-01,
- 1.961407762232199e-01, 8.722503785537784e-02, 1.703153418385261e-02}};
-double tab_ltpf_den_48000[4][13] = {
- {0.000000000000000e+00, 1.082359386659387e-02, 3.608969221303979e-02,
- 7.676401468099964e-02, 1.241530577501703e-01, 1.627596438300696e-01,
- 1.776771417779109e-01, 1.627596438300696e-01, 1.241530577501703e-01,
- 7.676401468099964e-02, 3.608969221303979e-02, 1.082359386659387e-02,
- 0.000000000000000e+00},
- {0.000000000000000e+00, 7.041404930459358e-03, 2.819702319820420e-02,
- 6.547044935127551e-02, 1.124647986743299e-01, 1.548418956489015e-01,
- 1.767122381341857e-01, 1.691507213057663e-01, 1.352901577989766e-01,
- 8.851425011427483e-02, 4.499353848562444e-02, 1.557613714732002e-02,
- 2.039721956502016e-03},
- {0.000000000000000e+00, 4.146998467444788e-03, 2.135757310741917e-02,
- 5.482735584552816e-02, 1.004971444643720e-01, 1.456060342830002e-01,
- 1.738439838565869e-01, 1.738439838565869e-01, 1.456060342830002e-01,
- 1.004971444643720e-01, 5.482735584552816e-02, 2.135757310741917e-02,
- 4.146998467444788e-03},
- {0.000000000000000e+00, 2.039721956502016e-03, 1.557613714732002e-02,
- 4.499353848562444e-02, 8.851425011427483e-02, 1.352901577989766e-01,
- 1.691507213057663e-01, 1.767122381341857e-01, 1.548418956489015e-01,
- 1.124647986743299e-01, 6.547044935127551e-02, 2.819702319820420e-02,
- 7.041404930459358e-03}};
diff --git a/system/embdrv/lc3_dec/Common/Tables/LongTermPostfilterCoefficients.hpp b/system/embdrv/lc3_dec/Common/Tables/LongTermPostfilterCoefficients.hpp
deleted file mode 100644
index 5ab9775599..0000000000
--- a/system/embdrv/lc3_dec/Common/Tables/LongTermPostfilterCoefficients.hpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * LongTermPostfilterCoefficients.hpp
- *
- * 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.
- */
-
-// LC3 Specification d09r01.pdf
-// Section 5.7.5 Long Term Postfiltering
-
-#ifndef LONG_TERM_POSTFILTER_COEFFICIENTS_H_
-#define LONG_TERM_POSTFILTER_COEFFICIENTS_H_
-
-extern double tab_resamp_filter[239];
-extern double tab_ltpf_interp_R[31];
-extern double tab_ltpf_interp_x12k8[15];
-extern double tab_ltpf_num_8000[4][3];
-extern double tab_ltpf_num_16000[4][3];
-extern double tab_ltpf_num_24000[4][5];
-extern double tab_ltpf_num_32000[4][7];
-extern double tab_ltpf_num_48000[4][11];
-extern double tab_ltpf_den_8000[4][5];
-extern double tab_ltpf_den_16000[4][5];
-extern double tab_ltpf_den_24000[4][7];
-extern double tab_ltpf_den_32000[4][9];
-extern double tab_ltpf_den_48000[4][13];
-
-#endif // LONG_TERM_POSTFILTER_COEFFICIENTS_H_
diff --git a/system/embdrv/lc3_dec/Common/Tables/MdctWindows.cpp b/system/embdrv/lc3_dec/Common/Tables/MdctWindows.cpp
deleted file mode 100644
index 595d5738b5..0000000000
--- a/system/embdrv/lc3_dec/Common/Tables/MdctWindows.cpp
+++ /dev/null
@@ -1,1573 +0,0 @@
-/*
- * MdctWindows.cpp
- *
- * 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.
- */
-
-// LC3 Specification d09r01.pdf
-// Section 5.7.2
-#include "MdctWindows.hpp"
-
-// LC3 Specification d09r01.pdf; Page 86 of 177
-
-// LC3 Specification d09r04_*implementorComments*
-// Section 3.7.3 Low delay MDCT windows
-// Section 3.7.3.1 10 ms Frame Duration
-
-// Section 5.7.2.1 w80 (d09r01.pdf)
-double w_N80[160] = {
- -7.078546706512391e-04, -2.098197727900724e-03, -4.525198076002370e-03,
- -8.233976327300612e-03, -1.337713096257934e-02, -1.999721557401502e-02,
- -2.800909464274782e-02, -3.721502082245055e-02, -4.731768261606175e-02,
- -5.794654834034055e-02, -6.867606753531441e-02, -7.904647440788692e-02,
- -8.859705468085925e-02, -9.688303623049199e-02, -1.034961241263523e-01,
- -1.080766457616878e-01, -1.103242262600913e-01, -1.099809851424550e-01,
- -1.068172142230882e-01, -1.006190418791648e-01, -9.116452506492527e-02,
- -7.820617483254730e-02, -6.146688124166948e-02, -4.063362855701623e-02,
- -1.536329520788766e-02, +1.470155068746303e-02, +4.989736509080558e-02,
- +9.050369257152079e-02, +1.366911019414417e-01, +1.884686389218322e-01,
- +2.456456803467095e-01, +3.077789078889820e-01, +3.741642373060188e-01,
- +4.438114799213576e-01, +5.154735456539700e-01, +5.876661722564289e-01,
- +6.587619767809000e-01, +7.270576699841359e-01, +7.908752989295335e-01,
- +8.486643364959733e-01, +8.991320235484349e-01, +9.413348145272842e-01,
- +9.747634827941575e-01, +9.994114730415857e-01, +1.015760373791603e+00,
- +1.024736164069697e+00, +1.027634294456205e+00, +1.025991493983836e+00,
- +1.021427210603284e+00, +1.015439859549357e+00, +1.009366925499550e+00,
- +1.003508162416449e+00, +9.988898206257559e-01, +9.953133902427869e-01,
- +9.925943919208190e-01, +9.905771957917731e-01, +9.891371616557014e-01,
- +9.881790747212391e-01, +9.876249269174586e-01, +9.874056275509585e-01,
- // LC3 Specification d09r01.pdf; Page 87 of 177
- +9.874524849192456e-01, +9.876951134084213e-01, +9.880640617030884e-01,
- +9.884926873551375e-01, +9.889230031022089e-01, +9.893074965384659e-01,
- +9.896146331889107e-01, +9.898319269347060e-01, +9.899693102025342e-01,
- +9.900603352632121e-01, +9.901575015155720e-01, +9.903255289051605e-01,
- +9.906303787150326e-01, +9.911298894709990e-01, +9.918665491182922e-01,
- +9.928619727154252e-01, +9.941156069136238e-01, +9.956033775539884e-01,
- +9.972793109558521e-01, +9.990784840729244e-01, +1.000922365901945e+00,
- +1.002728111386909e+00, +1.004416038098237e+00, +1.005919224127911e+00,
- +1.007189345025525e+00, +1.008200146369426e+00, +1.008949493525753e+00,
- +1.009458241425143e+00, +1.009768980817384e+00, +1.009940336228694e+00,
- +1.010039453539107e+00, +1.010132323996401e+00, +1.010272524848519e+00,
- +1.010494354532353e+00, +1.010808068774316e+00, +1.011201071127927e+00,
- +1.011641272406023e+00, +1.012080125934687e+00, +1.012458183122033e+00,
- +1.012706955800289e+00, +1.012755013843985e+00, +1.012530134411619e+00,
- +1.011962331100864e+00, +1.010982135506986e+00, +1.009512438049510e+00,
- +1.007460860286395e+00, +1.004708677491086e+00, +1.001111413242302e+00,
- +9.965041017623596e-01, +9.907199995730845e-01, +9.823765865983288e-01,
- +9.708821747608998e-01, +9.546732976073705e-01, +9.321553861564006e-01,
- +9.018003682081348e-01, +8.623984077953557e-01, +8.132817365236141e-01,
- +7.544551974836834e-01, +6.866580716267418e-01, +6.113488038789190e-01,
- +5.306181649316597e-01, +4.471309850999502e-01, +3.639114681156236e-01,
- +2.841647033392408e-01, +2.110209448747969e-01, +1.472287968327703e-01,
- +9.482665349502291e-02, +5.482436608328477e-02, +2.701461405056264e-02,
- +9.996743588367519e-03, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00};
-
-// Section 5.7.2.2 w160 (d09r01.pdf)
-double w_N160[320] = {
- -4.619898752628163e-04, -9.747166718929050e-04, -1.664473096973725e-03,
- -2.597106916737789e-03, -3.806285163352241e-03, -5.324608721716763e-03,
- -7.175885277771099e-03, -9.382480860899108e-03, -1.195270300743193e-02,
- -1.489528159506296e-02, -1.820666399965468e-02, -2.187570925786862e-02,
- -2.588471937157619e-02, -3.020862738245264e-02, -3.481597793538342e-02,
- -3.967067992672979e-02, -4.472698045914417e-02, -4.994225863256500e-02,
- -5.526334794593565e-02, -6.063717235243996e-02, -6.600961519440657e-02,
- -7.131966266443390e-02, -7.651178225890490e-02, -8.152964005319532e-02,
- -8.631137544905677e-02, -9.080411291245728e-02, -9.495377758870335e-02,
- -9.870736514214426e-02, -1.020202684361974e-01, -1.048438825017798e-01,
- -1.071382314127799e-01, -1.088690135027248e-01, -1.099969655786929e-01,
- -1.104898474883336e-01, -1.103225838568563e-01, -1.094621746650760e-01,
- -1.078834293141886e-01, -1.055612509762041e-01, -1.024650162703341e-01,
- -9.857014566194629e-02, -9.384684920715425e-02, -8.826309993000785e-02,
- -8.178792716809512e-02, -7.438785600211463e-02, -6.602189797715241e-02,
- -5.665655641133161e-02, -4.624456893420224e-02, -3.474585776145929e-02,
- -2.211581608120528e-02, -8.310425696208936e-03, +6.717697635290676e-03,
- // LC3 Specification d09r01.pdf; Page 88 of 177
- +2.300642061077823e-02, +4.060106462625085e-02, +5.953239090915557e-02,
- +7.983354189816511e-02, +1.015233140203748e-01, +1.246171387327525e-01,
- +1.491152519299797e-01, +1.750067399059861e-01, +2.022699854906251e-01,
- +2.308655379767671e-01, +2.607365124918583e-01, +2.918144694729168e-01,
- +3.240095704645023e-01, +3.572175180786021e-01, +3.913146885756875e-01,
- +4.261571642320424e-01, +4.615925445090212e-01, +4.974471592901086e-01,
- +5.335326819631583e-01, +5.696546730080154e-01, +6.056083823929643e-01,
- +6.411830842823245e-01, +6.761653499550255e-01, +7.103400549562944e-01,
- +7.434943718765665e-01, +7.754281892901473e-01, +8.059437233154637e-01,
- +8.348589373399948e-01, +8.620108336276733e-01, +8.872599706865123e-01,
- +9.104863121445679e-01, +9.315962496426278e-01, +9.505220861927248e-01,
- +9.672366712325431e-01, +9.817397501303696e-01, +9.940557180662704e-01,
- +1.004247514102417e+00, +1.012407428282884e+00, +1.018650990561848e+00,
- +1.023118841384460e+00, +1.025972450969440e+00, +1.027397523939210e+00,
- +1.027585830688143e+00, +1.026738673647482e+00, +1.025061777648234e+00,
- +1.022756514615106e+00, +1.020009139549275e+00, +1.016996499560845e+00,
- +1.013915946100629e+00, +1.011044869639164e+00, +1.007773858455400e+00,
- +1.004848753962734e+00, +1.002245009135684e+00, +9.999393169239009e-01,
- +9.979055415627330e-01, +9.961203379971326e-01, +9.945597525471822e-01,
- +9.932031606606762e-01, +9.920297273323891e-01, +9.910230654424902e-01,
- +9.901668953434221e-01, +9.894488374513719e-01, +9.888556356037892e-01,
- +9.883778520531268e-01, +9.880051626345804e-01, +9.877295459610343e-01,
- +9.875412739766566e-01, +9.874329809802893e-01, +9.873949921033299e-01,
- +9.874197049003676e-01, +9.874973205882319e-01, +9.876201238703241e-01,
- +9.877781920433015e-01, +9.879637979933339e-01, +9.881678007807095e-01,
- +9.883835200189653e-01, +9.886022219397892e-01, +9.888182771263505e-01,
- +9.890247977602895e-01, +9.892178658748239e-01, +9.893923680007577e-01,
- +9.895463342815009e-01, +9.896772011542693e-01, +9.897859195209235e-01,
- +9.898725363809847e-01, +9.899410789223559e-01, +9.899945557067980e-01,
- +9.900394023736973e-01, +9.900814722948890e-01, +9.901293790312005e-01,
- +9.901902265696609e-01, +9.902734448815004e-01, +9.903862280081246e-01,
- +9.905379830873822e-01, +9.907348826312993e-01, +9.909842592301273e-01,
- +9.912905118607647e-01, +9.916586940166509e-01, +9.920906151219310e-01,
- +9.925887208794144e-01, +9.931516528513824e-01, +9.937790866568735e-01,
- +9.944668184371617e-01, +9.952116634297566e-01, +9.960068616185641e-01,
- +9.968461329825753e-01, +9.977203369515556e-01, +9.986213520769593e-01,
- +9.995382582242990e-01, +1.000461955079660e+00, +1.001380551217109e+00,
- +1.002284871786226e+00, +1.003163845364970e+00, +1.004009147462043e+00,
- +1.004811375053364e+00, +1.005563968008037e+00, +1.006259855360867e+00,
- +1.006895570408563e+00, +1.007466616298057e+00, +1.007972441990187e+00,
- +1.008411468616852e+00, +1.008786009787269e+00, +1.009097763850333e+00,
- +1.009351762546296e+00, +1.009552401900961e+00, +1.009707093778162e+00,
- +1.009822090220407e+00, +1.009906958448099e+00, +1.009969021400474e+00,
- +1.010017890428877e+00, +1.010060809299530e+00, +1.010106564965965e+00,
- +1.010161131093372e+00, +1.010231078494249e+00, +1.010319484524512e+00,
- +1.010430470494512e+00, +1.010564099281000e+00, +1.010721360243234e+00,
- +1.010899655674578e+00, +1.011096993993037e+00, +1.011308167670753e+00,
- +1.011529185153809e+00, +1.011753008569803e+00, +1.011973876511603e+00,
- +1.012182837094955e+00, +1.012373028737774e+00, +1.012535058602453e+00,
- +1.012660975529858e+00, +1.012740575296603e+00, +1.012765922449960e+00,
- +1.012726958954961e+00, +1.012615904116265e+00, +1.012422888521601e+00,
- +1.012140460211194e+00, +1.011758810583150e+00, +1.011269960947744e+00,
- +1.010663676735228e+00, +1.009930754807923e+00, +1.009058249873833e+00,
- +1.008034308295421e+00, +1.006843352506855e+00, +1.005470005637052e+00,
- +1.003894772403371e+00, +1.002098854400575e+00, +1.000060686758758e+00,
- +9.977600196406868e-01, +9.951746430061121e-01, +9.922861082472264e-01,
- // LC3 Specification d09r01.pdf; Page 89 of 177
- +9.890757868707590e-01, +9.847362453480265e-01, +9.798613526271561e-01,
- +9.741378617337759e-01, +9.673331975559332e-01, +9.592539757044516e-01,
- +9.496984081652284e-01, +9.384634163826711e-01, +9.253567968750328e-01,
- +9.101986790930605e-01, +8.928338316495705e-01, +8.731437835983047e-01,
- +8.510420440685049e-01, +8.264839911291133e-01, +7.994681492797084e-01,
- +7.700431275216928e-01, +7.383028603058783e-01, +7.043814340356083e-01,
- +6.684616478236647e-01, +6.307755329382612e-01, +5.915799587176216e-01,
- +5.511703155400274e-01, +5.098915423728179e-01, +4.681017110047964e-01,
- +4.261772971493010e-01, +3.845172335531009e-01, +3.435228672445613e-01,
- +3.036004651973099e-01, +2.651434678028531e-01, +2.285283969438072e-01,
- +1.941021906320984e-01, +1.621735416384830e-01, +1.330015240938615e-01,
- +1.067840430193724e-01, +8.365057236623041e-02, +6.365188111381356e-02,
- +4.676538412257621e-02, +3.288072750732215e-02, +2.183057564646270e-02,
- +1.336381425803019e-02, +6.758124889697787e-03, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00};
-
-// Section 5.7.2.3 w240 (d09r01.pdf)
-double w_N240[480] = {
- -3.613496418928369e-04, -7.078546706512391e-04, -1.074443637110903e-03,
- -1.533478537964509e-03, -2.098197727900724e-03, -2.778420871815740e-03,
- -3.584129920673041e-03, -4.525198076002370e-03, -5.609327243712055e-03,
- -6.843234536105624e-03, -8.233976327300612e-03, -9.785314755557023e-03,
- -1.149880303071551e-02, -1.337713096257934e-02, -1.542181679511618e-02,
- -1.762979910961727e-02, -1.999721557401502e-02, -2.252080561390149e-02,
- -2.519406300389030e-02, -2.800909464274782e-02, -3.095765092956728e-02,
- -3.402996266948349e-02, -3.721502082245055e-02, -4.050053247568393e-02,
- -4.387219218706189e-02, -4.731768261606175e-02, -5.082325342672667e-02,
- -5.437166635159518e-02, -5.794654834034055e-02, -6.153426201732499e-02,
- -6.511708163113709e-02, -6.867606753531441e-02, -7.219447805250771e-02,
- -7.565695975592170e-02, -7.904647440788692e-02, -8.234442557322251e-02,
- -8.553324579905185e-02, -8.859705468085925e-02, -9.152091100798199e-02,
- -9.428847446755965e-02, -9.688303623049198e-02, -9.929123258537813e-02,
- -1.015008467688577e-01, -1.034961241263523e-01, -1.052637003544443e-01,
- -1.067939984687745e-01, -1.080766457616878e-01, -1.090997300590506e-01,
- // LC3 Specification d09r01.pdf; Page 90 of 177
- -1.098524491515805e-01, -1.103242262600913e-01, -1.105084619148789e-01,
- -1.103977408741932e-01, -1.099809851424550e-01, -1.092492774392824e-01,
- -1.081974227416502e-01, -1.068172142230882e-01, -1.050995803285455e-01,
- -1.030360111111103e-01, -1.006190418791648e-01, -9.784120023411771e-02,
- -9.469304216883027e-02, -9.116452506492527e-02, -8.724644532866996e-02,
- -8.293043914044632e-02, -7.820617483254730e-02, -7.306142427456862e-02,
- -6.748468182105991e-02, -6.146688124166948e-02, -5.499497258200362e-02,
- -4.805444424454820e-02, -4.063362855701623e-02, -3.272045590229335e-02,
- -2.430122582451853e-02, -1.536329520788766e-02, -5.891434269890659e-03,
- +4.126595858583295e-03, +1.470155068746303e-02, +2.584738191459814e-02,
- +3.757652772246801e-02, +4.989736509080558e-02, +6.282034030592902e-02,
- +7.635397728566121e-02, +9.050369257152079e-02, +1.052747118478660e-01,
- +1.206703467513333e-01, +1.366911019414417e-01, +1.533343890681390e-01,
- +1.705954709184399e-01, +1.884686389218322e-01, +2.069449962574092e-01,
- +2.260093000067393e-01, +2.456456803467095e-01, +2.658346019332584e-01,
- +2.865543814049772e-01, +3.077789078889820e-01, +3.294769437072290e-01,
- +3.516171481750350e-01, +3.741642373060188e-01, +3.970739591211551e-01,
- +4.203043046885219e-01, +4.438114799213576e-01, +4.675442291623012e-01,
- +4.914498631045615e-01, +5.154735456539700e-01, +5.395557644293222e-01,
- +5.636399817032525e-01, +5.876661722564289e-01, +6.115695310143157e-01,
- +6.352890592874099e-01, +6.587619767809000e-01, +6.819230974423550e-01,
- +7.047092819314779e-01, +7.270576699841359e-01, +7.489068963384272e-01,
- +7.701990187606995e-01, +7.908752989295335e-01, +8.108788692151807e-01,
- +8.301579139160681e-01, +8.486643364959733e-01, +8.663548164329093e-01,
- +8.831896853053627e-01, +8.991320235484349e-01, +9.141540563656075e-01,
- +9.282282546151819e-01, +9.413348145272842e-01, +9.534619388400459e-01,
- +9.646048250501910e-01, +9.747634827941575e-01, +9.839435385219192e-01,
- +9.921529097154242e-01, +9.994114730415857e-01, +1.005746084650236e+00,
- +1.011183971347815e+00, +1.015760373791603e+00, +1.019515072412387e+00,
- +1.022490937034641e+00, +1.024736164069697e+00, +1.026304095700693e+00,
- +1.027250978292214e+00, +1.027634294456205e+00, +1.027511063644843e+00,
- +1.026942795115598e+00, +1.025991493983836e+00, +1.024716149969084e+00,
- +1.023175976163407e+00, +1.021427210603284e+00, +1.019521566634239e+00,
- +1.017510118327508e+00, +1.015439859549357e+00, +1.013460916839174e+00,
- +1.011654901040475e+00, +1.009366925499550e+00, +1.007263182132894e+00,
- +1.005313192386866e+00, +1.003508162416449e+00, +1.001840787319378e+00,
- +1.000303927234380e+00, +9.988898206257559e-01, +9.975915283480670e-01,
- +9.964015284765968e-01, +9.953133902427869e-01, +9.943201078053212e-01,
- +9.934158959186011e-01, +9.925943919208190e-01, +9.918510277326026e-01,
- +9.911797988363887e-01, +9.905771957917731e-01, +9.900381047643838e-01,
- +9.895594394179152e-01, +9.891371616557014e-01, +9.887684373604154e-01,
- +9.884497924570929e-01, +9.881790747212391e-01, +9.879528358230726e-01,
- +9.877691368590689e-01, +9.876249269174586e-01, +9.875179947346887e-01,
- +9.874458127312921e-01, +9.874056275509585e-01, +9.873951115886979e-01,
- +9.874115368168944e-01, +9.874524849192456e-01, +9.875149888347144e-01,
- +9.875968894760857e-01, +9.876951134084213e-01, +9.878075819424549e-01,
- +9.879311998177238e-01, +9.880640617030884e-01, +9.882032571565917e-01,
- +9.883471084085503e-01, +9.884926873551375e-01, +9.886386592120545e-01,
- +9.887825578295630e-01, +9.889230031022089e-01, +9.890581715933395e-01,
- +9.891867674284610e-01, +9.893074965384659e-01, +9.894196399062921e-01,
- +9.895220757174378e-01, +9.896146331889107e-01, +9.896970346678272e-01,
- +9.897692596535289e-01, +9.898319269347060e-01, +9.898852572653667e-01,
- +9.899307640365727e-01, +9.899693102025343e-01, +9.900025692522435e-01,
- +9.900321562263099e-01, +9.900603352632121e-01, +9.900889812894406e-01,
- +9.901206586012907e-01, +9.901575015155720e-01, +9.902023946214220e-01,
- +9.902575406142213e-01, +9.903255289051605e-01, +9.904087914462694e-01,
- // LC3 Specification d09r01.pdf; Page 91 of 177
- +9.905096491583045e-01, +9.906303787150326e-01, +9.907727108894024e-01,
- +9.909387444078919e-01, +9.911298894709990e-01, +9.913476318763218e-01,
- +9.915928560402563e-01, +9.918665491182922e-01, +9.921691315380984e-01,
- +9.925010851461232e-01, +9.928619727154252e-01, +9.932519181564613e-01,
- +9.936700207375173e-01, +9.941156069136238e-01, +9.945873147903244e-01,
- +9.950837402063278e-01, +9.956033775539884e-01, +9.961439922621166e-01,
- +9.967034533921340e-01, +9.972793109558521e-01, +9.978690858367024e-01,
- +9.984697087896268e-01, +9.990784840729244e-01, +9.996919011206490e-01,
- +1.000308193833526e+00, +1.000922365901945e+00, +1.001532636590676e+00,
- +1.002135464655177e+00, +1.002728111386909e+00, +1.003307449770187e+00,
- +1.003870934089686e+00, +1.004416038098237e+00, +1.004940548815171e+00,
- +1.005442141810160e+00, +1.005919224127911e+00, +1.006370303149314e+00,
- +1.006793927824538e+00, +1.007189345025525e+00, +1.007555573455895e+00,
- +1.007892674961336e+00, +1.008200146369426e+00, +1.008478423284851e+00,
- +1.008727884997619e+00, +1.008949493525753e+00, +1.009144112734761e+00,
- +1.009313224929575e+00, +1.009458241425143e+00, +1.009581280555682e+00,
- +1.009684090687164e+00, +1.009768980817384e+00, +1.009838308708799e+00,
- +1.009894548257807e+00, +1.009940336228694e+00, +1.009977916643680e+00,
- +1.010010230290263e+00, +1.010039453539107e+00, +1.010068202038694e+00,
- +1.010098388689342e+00, +1.010132323996401e+00, +1.010171656775640e+00,
- +1.010218096148412e+00, +1.010272524848519e+00, +1.010336490294771e+00,
- +1.010410221483215e+00, +1.010494354532353e+00, +1.010588873699422e+00,
- +1.010693501186928e+00, +1.010808068774316e+00, +1.010931436739342e+00,
- +1.011062876503041e+00, +1.011201071127927e+00, +1.011344700694417e+00,
- +1.011491904228184e+00, +1.011641272406023e+00, +1.011790282474963e+00,
- +1.011937567254485e+00, +1.012080125934687e+00, +1.012216235487353e+00,
- +1.012342907951334e+00, +1.012458183122033e+00, +1.012558879696851e+00,
- +1.012642857380847e+00, +1.012706955800289e+00, +1.012748952907404e+00,
- +1.012765799894453e+00, +1.012755013843985e+00, +1.012713798678211e+00,
- +1.012639775003457e+00, +1.012530134411619e+00, +1.012382309473470e+00,
- +1.012194068117524e+00, +1.011962331100864e+00, +1.011685173724601e+00,
- +1.011359143572147e+00, +1.010982135506986e+00, +1.010550715971368e+00,
- +1.010062133151922e+00, +1.009512438049510e+00, +1.008898689394160e+00,
- +1.008215923600973e+00, +1.007460860286395e+00, +1.006627741823389e+00,
- +1.005712337656749e+00, +1.004708677491086e+00, +1.003611467285588e+00,
- +1.002414286392268e+00, +1.001111413242302e+00, +9.996961651093181e-01,
- +9.981625949525345e-01, +9.965041017623596e-01, +9.947148884277037e-01,
- +9.927891912841345e-01, +9.907199995730845e-01, +9.884793707533194e-01,
- +9.855347660016696e-01, +9.823765865983286e-01, +9.789747333404933e-01,
- +9.751623811486372e-01, +9.708821747608998e-01, +9.660805524695870e-01,
- +9.606976399184645e-01, +9.546732976073706e-01, +9.479479345282376e-01,
- +9.404609052933396e-01, +9.321553861564006e-01, +9.229775478442888e-01,
- +9.128745354570823e-01, +9.018003682081348e-01, +8.897163275605041e-01,
- +8.765908974996186e-01, +8.623984077953557e-01, +8.471200801854385e-01,
- +8.307479727020245e-01, +8.132817365236141e-01, +7.947291447585267e-01,
- +7.751108841891807e-01, +7.544551974836834e-01, +7.327963552921717e-01,
- +7.101790843209148e-01, +6.866580716267418e-01, +6.622962432368731e-01,
- +6.371684119604742e-01, +6.113488038789190e-01, +5.849206604934815e-01,
- +5.579747428663487e-01, +5.306181649316717e-01, +5.029523957059122e-01,
- +4.750868825511614e-01, +4.471309850999535e-01, +4.192049917945288e-01,
- +3.914252910998820e-01, +3.639114681156252e-01, +3.367837772954476e-01,
- +3.101627843160973e-01, +2.841647033392418e-01, +2.589033711808454e-01,
- +2.344880603710975e-01, +2.110209448747974e-01, +1.885997642296488e-01,
- +1.673100807904834e-01, +1.472287968327706e-01, +1.284223074167396e-01,
- +1.109422548710344e-01, +9.482665349502306e-02, +8.009914366829558e-02,
- +6.676765847398403e-02, +5.482436608328485e-02, +4.424588851571281e-02,
- // LC3 Specification d09r01.pdf; Page 92 of 177
- +3.499361000717621e-02, +2.701461405056267e-02, +2.024370180670145e-02,
- +1.460796755137538e-02, +9.996743588367531e-03, +5.305235098871444e-03,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00};
-
-// Section 5.7.2.4 w320 (d09r01.pdf)
-double w_N320[640] = {
- -3.021153494057143e-04, -5.867737487939294e-04, -8.366504004139796e-04,
- -1.126635355725494e-03, -1.470492941694331e-03, -1.873473391018495e-03,
- -2.339292362082021e-03, -2.872008069419264e-03, -3.476256385086407e-03,
- -4.155963816705528e-03, -4.914563787665504e-03, -5.755172503953251e-03,
- -6.680623380533122e-03, -7.693816924650567e-03, -8.796760749750191e-03,
- -9.990503073705982e-03, -1.127574117138621e-02, -1.265334152129685e-02,
- -1.412438986522702e-02, -1.568889620430290e-02, -1.734512089366117e-02,
- -1.909097368362797e-02, -2.092546711168754e-02, -2.284684792818856e-02,
- -2.485207716234951e-02, -2.693746704328349e-02, -2.909952486193999e-02,
- -3.133504629493832e-02, -3.363960728361352e-02, -3.600820974457969e-02,
- -3.843601741746971e-02, -4.091746034850161e-02, -4.344654894948344e-02,
- -4.601786724624048e-02, -4.862598509282497e-02, -5.126474204655663e-02,
- -5.392644753556616e-02, -5.660384311081047e-02, -5.929116747072080e-02,
- -6.198268202511926e-02, -6.467025548071184e-02, -6.734542216184526e-02,
- -7.000099017198280e-02, -7.263057011354321e-02, -7.522784961377151e-02,
- -7.778525942347714e-02, -8.029480247839878e-02, -8.274924535373614e-02,
- -8.514125464087215e-02, -8.746379123238275e-02, -8.971069341834263e-02,
- -9.187564084638347e-02, -9.395176975347193e-02, -9.593137735886889e-02,
- -9.780843257659243e-02, -9.957851303827886e-02, -1.012361165314596e-01,
- // LC3 Specification d09r01.pdf; Page 93 of 177
- -1.027741036495644e-01, -1.041861222641119e-01, -1.054680247057000e-01,
- -1.066160875985523e-01, -1.076255384835563e-01, -1.084912299471198e-01,
- -1.092087422379003e-01, -1.097736146613313e-01, -1.101808861640070e-01,
- -1.104271876052675e-01, -1.105108362290460e-01, -1.104281465492726e-01,
- -1.101739218186236e-01, -1.097437360338336e-01, -1.091353125572511e-01,
- -1.083467335729228e-01, -1.073739938306107e-01, -1.062130155324388e-01,
- -1.048606145834788e-01, -1.033132401525343e-01, -1.015673163469357e-01,
- -9.962005506126154e-02, -9.746803229469267e-02, -9.510723623306666e-02,
- -9.253303383231506e-02, -8.974125216128212e-02, -8.672877689119252e-02,
- -8.349213839083708e-02, -8.002639902061687e-02, -7.632679536516856e-02,
- -7.238806162166744e-02, -6.820576796149519e-02, -6.377611429172260e-02,
- -5.909386001558149e-02, -5.415316322402774e-02, -4.894812724598650e-02,
- -4.347347112195197e-02, -3.772461300253332e-02, -3.169587609244436e-02,
- -2.538179830690266e-02, -1.877689096555516e-02, -1.187461378850388e-02,
- -4.669099247423082e-03, +2.844096748870385e-03, +1.066976124794342e-02,
- +1.881355950582949e-02, +2.728156010437695e-02, +3.607810469851272e-02,
- +4.520702759803914e-02, +5.467238802204326e-02, +6.447866054615346e-02,
- +7.462862199422061e-02, +8.512490568723846e-02, +9.596983987496970e-02,
- +1.071650779014335e-01, +1.187115850305241e-01, +1.306101067250375e-01,
- +1.428596447589721e-01, +1.554584725339102e-01, +1.684041609371527e-01,
- +1.816947894623263e-01, +1.953273880886783e-01, +2.092963206850239e-01,
- +2.235945635254679e-01, +2.382160219461597e-01, +2.531529721334063e-01,
- +2.683961570569586e-01, +2.839361392493072e-01, +2.997624255177811e-01,
- +3.158619077906196e-01, +3.322210551086769e-01, +3.488264676990591e-01,
- +3.656640377499646e-01, +3.827152968157059e-01, +3.999611859760947e-01,
- +4.173843265025887e-01, +4.349669624916473e-01, +4.526876397402144e-01,
- +4.705242008503956e-01, +4.884539254831315e-01, +5.064545550235134e-01,
- +5.245006748662190e-01, +5.425674372882107e-01, +5.606312044701524e-01,
- +5.786672646386708e-01, +5.966477035050948e-01, +6.145458904162185e-01,
- +6.323361944662236e-01, +6.499926319211774e-01, +6.674874032292857e-01,
- +6.847932667399612e-01, +7.018835463513400e-01, +7.187322544823347e-01,
- +7.353128213893310e-01, +7.516001985652684e-01, +7.675699252273948e-01,
- +7.831974571624924e-01, +7.984583859818390e-01, +8.133295347030278e-01,
- +8.277892271515950e-01, +8.418178561101360e-01, +8.553961300139363e-01,
- +8.685068980898102e-01, +8.811334436653052e-01, +8.932596784799233e-01,
- +9.048748835980528e-01, +9.159657608120536e-01, +9.265215299450000e-01,
- +9.365339988633418e-01, +9.459977028429117e-01, +9.549088408436811e-01,
- +9.632658122557368e-01, +9.710688896122810e-01, +9.783204156360773e-01,
- +9.850226760127131e-01, +9.911792082081333e-01, +9.967989944502682e-01,
- +1.001894024615659e+00, +1.006474342231823e+00, +1.010552057109195e+00,
- +1.014142538208007e+00, +1.017262593268930e+00, +1.019928842669923e+00,
- +1.022159867011177e+00, +1.023976320927187e+00, +1.025400734608122e+00,
- +1.026455340400072e+00, +1.027164510654160e+00, +1.027552729180790e+00,
- +1.027644462380432e+00, +1.027463246660797e+00, +1.027035903410657e+00,
- +1.026389068000259e+00, +1.025548201799728e+00, +1.024537134749709e+00,
- +1.023380803775376e+00, +1.022103695693341e+00, +1.020728359657958e+00,
- +1.019275334687329e+00, +1.017765178792830e+00, +1.016217355867531e+00,
- +1.014665311686846e+00, +1.013249071090664e+00, +1.011948006992127e+00,
- +1.010189090179223e+00, +1.008557961167850e+00, +1.007011287608451e+00,
- +1.005548764575910e+00, +1.004168417268956e+00, +1.002867268893035e+00,
- +1.001641769115897e+00, +1.000489068954641e+00, +9.994060799749374e-01,
- +9.983898865406841e-01, +9.974370849972721e-01, +9.965444836911705e-01,
- +9.957098545943852e-01, +9.949302413030897e-01, +9.942024045863540e-01,
- +9.935241604969254e-01, +9.928930430130044e-01, +9.923068103443909e-01,
- +9.917633778190438e-01, +9.912597642374404e-01, +9.907954498484041e-01,
- +9.903677893656558e-01, +9.899751611066148e-01, +9.896160337369861e-01,
- // LC3 Specification d09r01.pdf; Page 94 of 177
- +9.892890160408989e-01, +9.889928511129679e-01, +9.887260333430423e-01,
- +9.884868721088945e-01, +9.882751039537586e-01, +9.880892168751595e-01,
- +9.879277114724612e-01, +9.877898261218510e-01, +9.876743442038471e-01,
- +9.875807496078497e-01, +9.875072021876561e-01, +9.874529447589979e-01,
- +9.874169741527905e-01, +9.873984685207834e-01, +9.873958301311858e-01,
- +9.874080027710336e-01, +9.874343401290739e-01, +9.874736235387018e-01,
- +9.875243137719285e-01, +9.875856201221135e-01, +9.876563785063032e-01,
- +9.877358921155149e-01, +9.878225576787804e-01, +9.879150968481590e-01,
- +9.880132731565830e-01, +9.881156946084619e-01, +9.882211314188272e-01,
- +9.883289032519310e-01, +9.884378310018685e-01, +9.885476787868710e-01,
- +9.886568414746639e-01, +9.887645868459630e-01, +9.888708540445242e-01,
- +9.889744320992592e-01, +9.890747269455915e-01, +9.891710038703801e-01,
- +9.892631024032380e-01, +9.893507219573624e-01, +9.894330645494204e-01,
- +9.895096919388534e-01, +9.895810813422480e-01, +9.896467469067676e-01,
- +9.897067365020641e-01, +9.897606930400666e-01, +9.898094478563998e-01,
- +9.898530133261707e-01, +9.898914705684924e-01, +9.899254194103574e-01,
- +9.899554202030650e-01, +9.899824494486951e-01, +9.900065116928948e-01,
- +9.900284805353695e-01, +9.900497484789281e-01, +9.900709561632662e-01,
- +9.900928358611601e-01, +9.901163920607219e-01, +9.901427479709606e-01,
- +9.901734275350572e-01, +9.902087332329851e-01, +9.902498637985275e-01,
- +9.902983686695558e-01, +9.903548501470234e-01, +9.904205084933333e-01,
- +9.904959297726740e-01, +9.905825150202904e-01, +9.906812569810133e-01,
- +9.907922087340426e-01, +9.909165464981378e-01, +9.910550740962871e-01,
- +9.912084614290896e-01, +9.913768610980639e-01, +9.915605826937839e-01,
- +9.917604214872976e-01, +9.919767175562684e-01, +9.922091101818779e-01,
- +9.924579135466506e-01, +9.927231225056266e-01, +9.930049538427406e-01,
- +9.933027281437943e-01, +9.936161084869942e-01, +9.939453714404443e-01,
- +9.942895145656371e-01, +9.946481676207727e-01, +9.950203031067961e-01,
- +9.954058173659507e-01, +9.958038713694317e-01, +9.962130271017117e-01,
- +9.966324689957675e-01, +9.970615306490058e-01, +9.974990583293081e-01,
- +9.979437430375855e-01, +9.983940572002874e-01, +9.988493116887893e-01,
- +9.993083430214909e-01, +9.997689221333534e-01, +1.000231131275969e+00,
- +1.000692135698996e+00, +1.001152013920163e+00, +1.001608526000461e+00,
- +1.002060493867275e+00, +1.002507212061815e+00, +1.002947129400411e+00,
- +1.003378909587027e+00, +1.003801368578070e+00, +1.004213810320699e+00,
- +1.004615386562846e+00, +1.005004618375781e+00, +1.005380628601598e+00,
- +1.005743282364652e+00, +1.006091510392348e+00, +1.006424907424988e+00,
- +1.006742427727669e+00, +1.007044321511378e+00, +1.007330218597112e+00,
- +1.007599401798709e+00, +1.007852064386603e+00, +1.008088176165563e+00,
- +1.008308033204578e+00, +1.008511247273756e+00, +1.008698144207627e+00,
- +1.008869515256392e+00, +1.009025659761512e+00, +1.009166718967367e+00,
- +1.009293362609020e+00, +1.009406398832440e+00, +1.009507017171120e+00,
- +1.009595264293017e+00, +1.009672145744679e+00, +1.009739084785160e+00,
- +1.009796675060142e+00, +1.009846137382005e+00, +1.009888083631667e+00,
- +1.009924092276850e+00, +1.009955384765721e+00, +1.009982268770147e+00,
- +1.010006298177305e+00, +1.010028618428735e+00, +1.010050254076988e+00,
- +1.010071952131355e+00, +1.010094366238073e+00, +1.010118917317053e+00,
- +1.010146497096682e+00, +1.010177110711677e+00, +1.010211755260102e+00,
- +1.010251003469427e+00, +1.010295468653759e+00, +1.010345234996637e+00,
- +1.010400316698172e+00, +1.010461564316351e+00, +1.010528615445659e+00,
- +1.010601521285347e+00, +1.010679788081867e+00, +1.010763905869062e+00,
- +1.010853429760676e+00, +1.010947547074519e+00, +1.011045953108263e+00,
- +1.011148486293359e+00, +1.011254397791134e+00, +1.011363082075863e+00,
- +1.011473302008831e+00, +1.011584996312149e+00, +1.011697416504599e+00,
- +1.011808919793469e+00, +1.011919264025716e+00, +1.012027240794153e+00,
- +1.012132151631041e+00, +1.012232734564333e+00, +1.012327560477901e+00,
- // LC3 Specification d09r01.pdf; Page 95 of 177
- +1.012416383754384e+00, +1.012497890726292e+00, +1.012570434021054e+00,
- +1.012633295255708e+00, +1.012685277016726e+00, +1.012725564992284e+00,
- +1.012752577651415e+00, +1.012765062889864e+00, +1.012762356719162e+00,
- +1.012743376077777e+00, +1.012706484200181e+00, +1.012650842226435e+00,
- +1.012575427778520e+00, +1.012479473490919e+00, +1.012361105121003e+00,
- +1.012219809594718e+00, +1.012054359992419e+00, +1.011864000215460e+00,
- +1.011647223869087e+00, +1.011402518267713e+00, +1.011129654652857e+00,
- +1.010826951260377e+00, +1.010492924436361e+00, +1.010126353960416e+00,
- +1.009725892479312e+00, +1.009290060983833e+00, +1.008817301052548e+00,
- +1.008305027555130e+00, +1.007752833675443e+00, +1.007157827358150e+00,
- +1.006518049344503e+00, +1.005831403532018e+00, +1.005095592119373e+00,
- +1.004308630055050e+00, +1.003467498305776e+00, +1.002569500413888e+00,
- +1.001612710105563e+00, +1.000594272975683e+00, +9.995111701168786e-01,
- +9.983609218719522e-01, +9.971409288327860e-01, +9.958488863050556e-01,
- +9.944818543153893e-01, +9.930375282832211e-01, +9.915146560759479e-01,
- +9.899136802423638e-01, +9.881930623810997e-01, +9.859422591203311e-01,
- +9.835667898378924e-01, +9.811423034808365e-01, +9.785214441250228e-01,
- +9.756636036109838e-01, +9.725453442532574e-01, +9.691456634185092e-01,
- +9.654406178310209e-01, +9.614043615076308e-01, +9.570113065179300e-01,
- +9.522367669696690e-01, +9.470548839544214e-01, +9.414403740008491e-01,
- +9.353691612846549e-01, +9.288190093977164e-01, +9.217662887169115e-01,
- +9.141896283466009e-01, +9.060694681113471e-01, +8.973891675497357e-01,
- +8.881332000806269e-01, +8.782893885841422e-01, +8.678469565343039e-01,
- +8.567970644671067e-01, +8.451334654019180e-01, +8.328542805780399e-01,
- +8.199594783897041e-01, +8.064511006873497e-01, +7.923346478686025e-01,
- +7.776204488292163e-01, +7.623206183595970e-01, +7.464486491227057e-01,
- +7.300205729992958e-01, +7.130567383226717e-01, +6.955805444755916e-01,
- +6.776173229836567e-01, +6.591955305148172e-01, +6.403486426892321e-01,
- +6.211072197441818e-01, +6.015049275244730e-01, +5.815787608870452e-01,
- +5.613674511156324e-01, +5.409188627354076e-01, +5.202736834971303e-01,
- +4.994780733459294e-01, +4.785774177949064e-01, +4.576172599874928e-01,
- +4.366490208265804e-01, +4.157221460415995e-01, +3.948856590950757e-01,
- +3.741903189229770e-01, +3.536868899553974e-01, +3.334260017756462e-01,
- +3.134586473252229e-01, +2.938337904395871e-01, +2.745992637590817e-01,
- +2.558030636168172e-01, +2.374902188466697e-01, +2.197036032185785e-01,
- +2.024855415115456e-01, +1.858749915117319e-01, +1.699067802117410e-01,
- +1.546132267478873e-01, +1.400238206749695e-01, +1.261637395672913e-01,
- +1.130534434072719e-01, +1.007084973747940e-01, +8.914024389873081e-02,
- +7.835612100141792e-02, +6.835821233920988e-02, +5.914211536028976e-02,
- +5.069893012340832e-02, +4.301717763585550e-02, +3.608020726673359e-02,
- +2.986316337017630e-02, +2.433722657129812e-02, +1.947675241971700e-02,
- +1.525710171255895e-02, +1.163787492636240e-02, +8.433087782643718e-03,
- +4.449668997344735e-03, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- // LC3 Specification d09r01.pdf; Page 96 of 177
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00};
-
-// Section 5.7.2.5 w480 (d09r01.pdf)
-double w_N480[960] = {
- -2.353032150516754e-04, -4.619898752628163e-04, -6.262931535610879e-04,
- -7.929180432976445e-04, -9.747166718929050e-04, -1.180256894474562e-03,
- -1.409209039594871e-03, -1.664473096973725e-03, -1.946591608170231e-03,
- -2.257081732588478e-03, -2.597106916737789e-03, -2.967607624839524e-03,
- -3.370454877988472e-03, -3.806285163352241e-03, -4.276873767639064e-03,
- -4.782469904501813e-03, -5.324608721716763e-03, -5.903403814095400e-03,
- -6.520419726599805e-03, -7.175885277771099e-03, -7.871422820642307e-03,
- -8.606586039759667e-03, -9.382480860899108e-03, -1.019827182163307e-02,
- -1.105520547739066e-02, -1.195270300743193e-02, -1.289205910303846e-02,
- -1.387263484323160e-02, -1.489528159506296e-02, -1.595856621933800e-02,
- -1.706288556735433e-02, -1.820666399965468e-02, -1.939065975232718e-02,
- -2.061355417582714e-02, -2.187570925786862e-02, -2.317526315266411e-02,
- -2.451227449041489e-02, -2.588471937157619e-02, -2.729263737090799e-02,
- -2.873390902713615e-02, -3.020862738245264e-02, -3.171440372994384e-02,
- -3.325098858986303e-02, -3.481597793538342e-02, -3.640892406933019e-02,
- -3.802742318209150e-02, -3.967067992672979e-02, -4.133575417353826e-02,
- -4.302203371734278e-02, -4.472698045914417e-02, -4.645022292934329e-02,
- -4.818891490266687e-02, -4.994225863256500e-02, -5.170690802826666e-02,
- -5.348162036097223e-02, -5.526334794593565e-02, -5.705123152423822e-02,
- -5.884271749745559e-02, -6.063717235243996e-02, -6.243104027829089e-02,
- -6.422303545004304e-02, -6.600961519440657e-02, -6.778962269634495e-02,
- -6.955996868581379e-02, -7.131966266443390e-02, -7.306581273272733e-02,
- -7.479758913001458e-02, -7.651178225890490e-02, -7.820711420768856e-02,
- -7.988010693411644e-02, -8.152964005319532e-02, -8.315237353264004e-02,
- // LC3 Specification d09r01.pdf; Page 97 of 177
- -8.474728946770714e-02, -8.631137544905677e-02, -8.784374452959058e-02,
- -8.934164364321417e-02, -9.080411291245728e-02, -9.222795761428432e-02,
- -9.361232867223340e-02, -9.495377758870335e-02, -9.625155313139856e-02,
- -9.750284620437569e-02, -9.870736514214426e-02, -9.986271288271026e-02,
- -1.009680221406219e-01, -1.020202684361974e-01, -1.030183804850491e-01,
- -1.039596356759290e-01, -1.048438825017798e-01, -1.056686838192766e-01,
- -1.064342821660323e-01, -1.071382314127799e-01, -1.077799961121537e-01,
- -1.083570625865931e-01, -1.088690135027248e-01, -1.093135588677235e-01,
- -1.096903559498340e-01, -1.099969655786929e-01, -1.102332261219973e-01,
- -1.103972812085189e-01, -1.104898474883336e-01, -1.105086416532167e-01,
- -1.104537426996073e-01, -1.103225838568563e-01, -1.101145827722143e-01,
- -1.098276928170364e-01, -1.094621746650760e-01, -1.090163960055733e-01,
- -1.084908852561722e-01, -1.078834293141886e-01, -1.071937180231978e-01,
- -1.064196358069465e-01, -1.055612509762041e-01, -1.046162812518618e-01,
- -1.035849043557610e-01, -1.024650162703341e-01, -1.012568997532046e-01,
- -9.995864571932928e-02, -9.857014566194627e-02, -9.708911135857967e-02,
- -9.551545820689084e-02, -9.384684920715425e-02, -9.208300062891550e-02,
- -9.022171021406450e-02, -8.826309993000785e-02, -8.620493821803937e-02,
- -8.404742152815330e-02, -8.178792716809512e-02, -7.942625026703617e-02,
- -7.695980775819990e-02, -7.438785600211463e-02, -7.170797002873608e-02,
- -6.891994783815969e-02, -6.602189797715241e-02, -6.301349420724424e-02,
- -5.989191912667712e-02, -5.665655641133161e-02, -5.330406164482222e-02,
- -4.983427241976235e-02, -4.624456893420224e-02, -4.253455686336916e-02,
- -3.870195772538443e-02, -3.474585776145929e-02, -3.066341518682682e-02,
- -2.645425077642105e-02, -2.211581608120528e-02, -1.764740541599136e-02,
- -1.304581363895818e-02, -8.310425696208936e-03, -3.438268661133170e-03,
- +1.570315476576933e-03, +6.717697635290676e-03, +1.200477020244778e-02,
- +1.743398319747869e-02, +2.300642061077823e-02, +2.872481423270595e-02,
- +3.458896350634671e-02, +4.060106462625085e-02, +4.676102915752826e-02,
- +5.307133911821893e-02, +5.953239090915557e-02, +6.614647812869151e-02,
- +7.291293184312803e-02, +7.983354189816511e-02, +8.690807412770696e-02,
- +9.413813765275064e-02, +1.015233140203748e-01, +1.090651518336202e-01,
- +1.167626546016197e-01, +1.246171387327525e-01, +1.326272948938113e-01,
- +1.407938190608664e-01, +1.491152519299797e-01, +1.575921408388593e-01,
- +1.662224799248571e-01, +1.750067399059861e-01, +1.839431938620024e-01,
- +1.930318183054904e-01, +2.022699854906251e-01, +2.116567430906184e-01,
- +2.211888523410642e-01, +2.308655379767671e-01, +2.406837992341654e-01,
- +2.506420640291662e-01, +2.607365124918583e-01, +2.709659073501196e-01,
- +2.813259021832532e-01, +2.918144694729168e-01, +3.024270279840051e-01,
- +3.131603499997996e-01, +3.240095704645023e-01, +3.349719592361666e-01,
- +3.460422935204829e-01, +3.572175180786021e-01, +3.684915649120530e-01,
- +3.798595119591716e-01, +3.913146885756875e-01, +4.028532873867052e-01,
- +4.144688328137527e-01, +4.261571642320424e-01, +4.379113897565727e-01,
- +4.497256320417501e-01, +4.615925445090212e-01, +4.735067030065239e-01,
- +4.854600184866710e-01, +4.974471592901086e-01, +5.094597228333853e-01,
- +5.214909841729947e-01, +5.335326819631583e-01, +5.455789811615239e-01,
- +5.576217157959890e-01, +5.696546730080154e-01, +5.816685576268035e-01,
- +5.936560624526468e-01, +6.056083823929643e-01, +6.175192060085208e-01,
- +6.293796611336280e-01, +6.411830842823245e-01, +6.529203544876097e-01,
- +6.645840786371451e-01, +6.761653499550255e-01, +6.876573952173626e-01,
- +6.990511539119996e-01, +7.103400549562944e-01, +7.215149331458728e-01,
- +7.325691772738999e-01, +7.434943718765665e-01, +7.542846327442048e-01,
- +7.649313654540612e-01, +7.754281892901473e-01, +7.857670170752049e-01,
- +7.959414651061612e-01, +8.059437233154637e-01, +8.157687070715176e-01,
- +8.254086223972127e-01, +8.348589373399948e-01, +8.441125827416620e-01,
- +8.531651194538425e-01, +8.620108336276733e-01, +8.706456337542150e-01,
- // LC3 Specification d09r01.pdf; Page 98 of 177
- +8.790631561061171e-01, +8.872599706865123e-01, +8.952313288619367e-01,
- +9.029751680353524e-01, +9.104863121445679e-01, +9.177625550620636e-01,
- +9.247997426966093e-01, +9.315962496426278e-01, +9.381494858921667e-01,
- +9.444588390359354e-01, +9.505220861927248e-01, +9.563402921286364e-01,
- +9.619114522936701e-01, +9.672366712325431e-01, +9.723156637834687e-01,
- +9.771501187120180e-01, +9.817397501303696e-01, +9.860865871353246e-01,
- +9.901906380163595e-01, +9.940557180662704e-01, +9.976842395284637e-01,
- +1.001080961257010e+00, +1.004247514102417e+00, +1.007188578458507e+00,
- +1.009906654565108e+00, +1.012407428282884e+00, +1.014694702432600e+00,
- +1.016774659209400e+00, +1.018650990561848e+00, +1.020330464463111e+00,
- +1.021817328911793e+00, +1.023118841384460e+00, +1.024240262467000e+00,
- +1.025189721888128e+00, +1.025972450969440e+00, +1.026596938589443e+00,
- +1.027069179375841e+00, +1.027397523939210e+00, +1.027587902203109e+00,
- +1.027648951922701e+00, +1.027585830688143e+00, +1.027408519661012e+00,
- +1.027122986826984e+00, +1.026738673647482e+00, +1.026261663878092e+00,
- +1.025701002415063e+00, +1.025061777648234e+00, +1.024353980976701e+00,
- +1.023582385618774e+00, +1.022756514615106e+00, +1.021880604350422e+00,
- +1.020963871317665e+00, +1.020009139549275e+00, +1.019027285501251e+00,
- +1.018019442784231e+00, +1.016996499560845e+00, +1.015957433206324e+00,
- +1.014923441259795e+00, +1.013915946100629e+00, +1.013047565149327e+00,
- +1.012216130365610e+00, +1.011044869639164e+00, +1.009914592130044e+00,
- +1.008824888092573e+00, +1.007773858455400e+00, +1.006761700412993e+00,
- +1.005786648810854e+00, +1.004848753962734e+00, +1.003946083413733e+00,
- +1.003078846506546e+00, +1.002245009135684e+00, +1.001444733905817e+00,
- +1.000676188436651e+00, +9.999393169239009e-01, +9.992320848298057e-01,
- +9.985548127155425e-01, +9.979055415627330e-01, +9.972842679758880e-01,
- +9.966890948441745e-01, +9.961203379971326e-01, +9.955761256313581e-01,
- +9.950565724564597e-01, +9.945597525471822e-01, +9.940860378486615e-01,
- +9.936337788972491e-01, +9.932031606606759e-01, +9.927921871265732e-01,
- +9.924015177880798e-01, +9.920297273323891e-01, +9.916767775088281e-01,
- +9.913408767719142e-01, +9.910230654424902e-01, +9.907216425865902e-01,
- +9.904366799536263e-01, +9.901668953434221e-01, +9.899131011580791e-01,
- +9.896735637374597e-01, +9.894488374513719e-01, +9.892374835404283e-01,
- +9.890401927796704e-01, +9.888556356037892e-01, +9.886843467692753e-01,
- +9.885247606051014e-01, +9.883778520531268e-01, +9.882423270582524e-01,
- +9.881185638915363e-01, +9.880051626345804e-01, +9.879032023766432e-01,
- +9.878111744348976e-01, +9.877295459610343e-01, +9.876571983429736e-01,
- +9.875949843246187e-01, +9.875412739766566e-01, +9.874969061399389e-01,
- +9.874606249127551e-01, +9.874329809802893e-01, +9.874126414437681e-01,
- +9.874004750404033e-01, +9.873949921033299e-01, +9.873969162747074e-01,
- +9.874049060317581e-01, +9.874197049003676e-01, +9.874399717110517e-01,
- +9.874663281231737e-01, +9.874973205882319e-01, +9.875338926695315e-01,
- +9.875746535410983e-01, +9.876201238703241e-01, +9.876689801932402e-01,
- +9.877221556193183e-01, +9.877781920433015e-01, +9.878376489591358e-01,
- +9.878991990245439e-01, +9.879637979933339e-01, +9.880300303653743e-01,
- +9.880984675859855e-01, +9.881678007807095e-01, +9.882390300097154e-01,
- +9.883107693992456e-01, +9.883835200189653e-01, +9.884560159878955e-01,
- +9.885294200392185e-01, +9.886022219397892e-01, +9.886749404176028e-01,
- +9.887466261142505e-01, +9.888182771263505e-01, +9.888882480852147e-01,
- +9.889574384705896e-01, +9.890247977602895e-01, +9.890911247701029e-01,
- +9.891551701556196e-01, +9.892178658748239e-01, +9.892779555818088e-01,
- +9.893365186903538e-01, +9.893923680007577e-01, +9.894462830852175e-01,
- +9.894972124952000e-01, +9.895463342815009e-01, +9.895923617530382e-01,
- +9.896362652966239e-01, +9.896772011542693e-01, +9.897162195263046e-01,
- +9.897520286480039e-01, +9.897859195209235e-01, +9.898170267411330e-01,
- +9.898462068764986e-01, +9.898725363809847e-01, +9.898975138787787e-01,
- // LC3 Specification d09r01.pdf; Page 99 of 177
- +9.899200050208486e-01, +9.899410789223559e-01, +9.899600605054418e-01,
- +9.899782261038060e-01, +9.899945557067980e-01, +9.900103500807507e-01,
- +9.900248320990181e-01, +9.900394023736973e-01, +9.900532105829365e-01,
- +9.900674746047259e-01, +9.900814722948890e-01, +9.900966926051257e-01,
- +9.901122448734595e-01, +9.901293790312005e-01, +9.901474648912307e-01,
- +9.901680598867444e-01, +9.901902265696609e-01, +9.902151896501201e-01,
- +9.902424418296485e-01, +9.902734448815004e-01, +9.903071270768942e-01,
- +9.903448913950654e-01, +9.903862280081246e-01, +9.904324484666853e-01,
- +9.904825650601110e-01, +9.905379830873822e-01, +9.905980602136440e-01,
- +9.906640366554630e-01, +9.907348826312993e-01, +9.908120376822228e-01,
- +9.908947858311721e-01, +9.909842592301273e-01, +9.910795247770178e-01,
- +9.911819240108124e-01, +9.912905118607647e-01, +9.914064705361564e-01,
- +9.915288011543961e-01, +9.916586940166509e-01, +9.917952720685562e-01,
- +9.919396217291009e-01, +9.920906151219310e-01, +9.922495028313456e-01,
- +9.924152398352751e-01, +9.925887208794144e-01, +9.927688708468421e-01,
- +9.929569112537944e-01, +9.931516528513824e-01, +9.933539244159140e-01,
- +9.935626893131695e-01, +9.937790866568735e-01, +9.940016434044485e-01,
- +9.942312024833810e-01, +9.944668184371617e-01, +9.947093441694513e-01,
- +9.949572854565533e-01, +9.952116634297566e-01, +9.954712635321227e-01,
- +9.957367951478069e-01, +9.960068616185641e-01, +9.962823025614079e-01,
- +9.965617986382630e-01, +9.968461329825753e-01, +9.971338271912752e-01,
- +9.974256691222113e-01, +9.977203369515556e-01, +9.980185087055744e-01,
- +9.983185871761977e-01, +9.986213520769593e-01, +9.989255426466267e-01,
- +9.992317314100975e-01, +9.995382582242990e-01, +9.998461160718275e-01,
- +1.000153907612080e+00, +1.000461955079660e+00, +1.000768859280338e+00,
- +1.001075613053728e+00, +1.001380551217109e+00, +1.001684244734497e+00,
- +1.001985425397567e+00, +1.002284871786226e+00, +1.002580975161843e+00,
- +1.002874411368430e+00, +1.003163845364970e+00, +1.003450063374329e+00,
- +1.003731570287893e+00, +1.004009147462043e+00, +1.004281457582935e+00,
- +1.004549339226336e+00, +1.004811375053364e+00, +1.005068272394360e+00,
- +1.005318795748286e+00, +1.005563968008037e+00, +1.005802269635282e+00,
- +1.006034554002353e+00, +1.006259855360867e+00, +1.006479018139540e+00,
- +1.006690541428116e+00, +1.006895570408563e+00, +1.007093045696527e+00,
- +1.007283799246233e+00, +1.007466616298057e+00, +1.007642728426847e+00,
- +1.007811036585595e+00, +1.007972441990187e+00, +1.008125875904472e+00,
- +1.008272602383284e+00, +1.008411468616852e+00, +1.008543573152632e+00,
- +1.008668018334797e+00, +1.008786009787269e+00, +1.008896526233555e+00,
- +1.009000766336071e+00, +1.009097763850333e+00, +1.009188880897370e+00,
- +1.009273163797313e+00, +1.009351762546296e+00, +1.009423944949143e+00,
- +1.009491175244507e+00, +1.009552401900961e+00, +1.009608886895764e+00,
- +1.009659973830751e+00, +1.009707093778162e+00, +1.009749238562067e+00,
- +1.009787744284661e+00, +1.009822090220407e+00, +1.009853706282597e+00,
- +1.009881498943010e+00, +1.009906958448099e+00, +1.009929567021562e+00,
- +1.009950573483366e+00, +1.009969021400474e+00, +1.009986499185054e+00,
- +1.010002363879044e+00, +1.010017890428877e+00, +1.010032170180360e+00,
- +1.010046722045583e+00, +1.010060809299530e+00, +1.010075674445289e+00,
- +1.010090449982098e+00, +1.010106564965965e+00, +1.010123226584120e+00,
- +1.010141762173145e+00, +1.010161131093372e+00, +1.010182635897876e+00,
- +1.010205587931660e+00, +1.010231078494249e+00, +1.010257950227988e+00,
- +1.010287732968580e+00, +1.010319484524512e+00, +1.010354079663767e+00,
- +1.010390635488037e+00, +1.010430470494512e+00, +1.010472266495074e+00,
- +1.010517096381509e+00, +1.010564099281000e+00, +1.010614266894512e+00,
- +1.010666285876455e+00, +1.010721360243234e+00, +1.010778416755264e+00,
- +1.010838252644461e+00, +1.010899655674578e+00, +1.010963729626641e+00,
- +1.011029191301694e+00, +1.011096993993037e+00, +1.011165861239173e+00,
- +1.011236610341260e+00, +1.011308167670753e+00, +1.011381453638912e+00,
- // LC3 Specification d09r01.pdf; Page 100 of 177
- +1.011454785713102e+00, +1.011529185153809e+00, +1.011603680910505e+00,
- +1.011678803938046e+00, +1.011753008569803e+00, +1.011827484797985e+00,
- +1.011900936547881e+00, +1.011973876511603e+00, +1.012044885003304e+00,
- +1.012114985644919e+00, +1.012182837094955e+00, +1.012249023976742e+00,
- +1.012312095063070e+00, +1.012373028737774e+00, +1.012430463679316e+00,
- +1.012484972246822e+00, +1.012535058602453e+00, +1.012581678169188e+00,
- +1.012623472898504e+00, +1.012660975529858e+00, +1.012692758750213e+00,
- +1.012719789201144e+00, +1.012740575296603e+00, +1.012755753887085e+00,
- +1.012763948841204e+00, +1.012765922449960e+00, +1.012760298661069e+00,
- +1.012747819936584e+00, +1.012726958954961e+00, +1.012698607692183e+00,
- +1.012661400539405e+00, +1.012615904116265e+00, +1.012560833005713e+00,
- +1.012497050269805e+00, +1.012422888521601e+00, +1.012339226241367e+00,
- +1.012244921966297e+00, +1.012140460211194e+00, +1.012024302085441e+00,
- +1.011897560567707e+00, +1.011758810583150e+00, +1.011608449127642e+00,
- +1.011445162723270e+00, +1.011269960947744e+00, +1.011081255645969e+00,
- +1.010879608424312e+00, +1.010663676735228e+00, +1.010434184200640e+00,
- +1.010189681124657e+00, +1.009930754807923e+00, +1.009655660215271e+00,
- +1.009365251564694e+00, +1.009058249873833e+00, +1.008734758578989e+00,
- +1.008393079963091e+00, +1.008034308295421e+00, +1.007656661215973e+00,
- +1.007260142622887e+00, +1.006843352506855e+00, +1.006407009542103e+00,
- +1.005949145170711e+00, +1.005470005637052e+00, +1.004967986424467e+00,
- +1.004443531995945e+00, +1.003894772403371e+00, +1.003321903663793e+00,
- +1.002723127308148e+00, +1.002098854400575e+00, +1.001447278873483e+00,
- +1.000768505317086e+00, +1.000060686758758e+00, +9.993242684851855e-01,
- +9.985573503390627e-01, +9.977600196406868e-01, +9.969306036935497e-01,
- +9.960694269553644e-01, +9.951746430061121e-01, +9.942466438407230e-01,
- +9.932837131068657e-01, +9.922861082472264e-01, +9.912523092989319e-01,
- +9.901827419790691e-01, +9.890757868707590e-01, +9.879313024174022e-01,
- +9.863553220272523e-01, +9.847362453480265e-01, +9.831750948772566e-01,
- +9.815583336011345e-01, +9.798613526271561e-01, +9.780617486993630e-01,
- +9.761574317374303e-01, +9.741378617337759e-01, +9.719990112065752e-01,
- +9.697327413658168e-01, +9.673331975559332e-01, +9.647915124057732e-01,
- +9.621011497566145e-01, +9.592539757044516e-01, +9.562427177295731e-01,
- +9.530600909726344e-01, +9.496984081652284e-01, +9.461498120176854e-01,
- +9.424071613625743e-01, +9.384634163826711e-01, +9.343112966094085e-01,
- +9.299449872197452e-01, +9.253567968750328e-01, +9.205404627076625e-01,
- +9.154896280575360e-01, +9.101986790930605e-01, +9.046620597741508e-01,
- +8.988755194372424e-01, +8.928338316495705e-01, +8.865337190368053e-01,
- +8.799712722567934e-01, +8.731437835983047e-01, +8.660476534563131e-01,
- +8.586812520174252e-01, +8.510420440685049e-01, +8.431297226886574e-01,
- +8.349435141989714e-01, +8.264839911291133e-01, +8.177505366573690e-01,
- +8.087449817124315e-01, +7.994681492797084e-01, +7.899235162194718e-01,
- +7.801137731566502e-01, +7.700431275216928e-01, +7.597145736971065e-01,
- +7.491330971820804e-01, +7.383028603058783e-01, +7.272298755824693e-01,
- +7.159201919962611e-01, +7.043814340356083e-01, +6.926196927377140e-01,
- +6.806438831866077e-01, +6.684616478236647e-01, +6.560830137986515e-01,
- +6.435179268559957e-01, +6.307755329382612e-01, +6.178641647786525e-01,
- +6.047954625702541e-01, +5.915799587176216e-01, +5.782289366005894e-01,
- +5.647535885752191e-01, +5.511703155400274e-01, +5.374905090437071e-01,
- +5.237263500445715e-01, +5.098915423728255e-01, +4.960008074926423e-01,
- +4.820662943337458e-01, +4.681017110048007e-01, +4.541216995958746e-01,
- +4.401421815729068e-01, +4.261772971493010e-01, +4.122417888542512e-01,
- +3.983499612526493e-01, +3.845172335531009e-01, +3.707583717376236e-01,
- +3.570886786795506e-01, +3.435228672445627e-01, +3.300763764703638e-01,
- +3.167640325043893e-01, +3.036004651973109e-01, +2.905996158436682e-01,
- +2.777758503744847e-01, +2.651434678028531e-01, +2.527161881181577e-01,
- // LC3 Specification d09r01.pdf; Page 101 of 177
- +2.405069849650012e-01, +2.285283969438072e-01, +2.167933432162879e-01,
- +2.053139897833021e-01, +1.941021906320988e-01, +1.831680872008943e-01,
- +1.725221947208913e-01, +1.621735416384834e-01, +1.521320683467849e-01,
- +1.424052801149985e-01, +1.330015240938615e-01, +1.239260664828526e-01,
- +1.151858295527293e-01, +1.067840430193724e-01, +9.872637505002878e-02,
- +9.101379000888035e-02, +8.365057236623055e-02, +7.663508305536153e-02,
- +6.997033405748826e-02, +6.365188111381365e-02, +5.768176015814392e-02,
- +5.205244216987966e-02, +4.676538412257621e-02, +4.180950541438362e-02,
- +3.718640251368464e-02, +3.288072750732215e-02, +2.889548499582958e-02,
- +2.520980565928884e-02, +2.183057564646272e-02, +1.872896194002638e-02,
- +1.592127815153420e-02, +1.336381425803020e-02, +1.108558877807282e-02,
- +8.943474189364638e-03, +6.758124889697787e-03, +3.504438130619497e-03,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- // LC3 Specification d09r01.pdf; Page 102 of 177
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00,
- +0.000000000000000e+00, +0.000000000000000e+00, +0.000000000000000e+00};
-
-// LC3 Specification d09r04_*implementorComments*
-// Section 3.7.3 Low delay MDCT windows
-// Section 3.7.3.2 7.5 ms Frame Duration
-
-// Section 3.7.3.2.1 w_7.5_60 (d09r04_*implementorComments*)
-double w_N60_7p5ms[120] = {
- 2.950608593187313e-03, 7.175411316438510e-03, 1.376953735371754e-02,
- 2.309535564877266e-02, 3.540362298325999e-02, 5.082893035710152e-02,
- 6.946962925951473e-02, 9.138842778133426e-02, 1.166045748296231e-01,
- 1.450735459839195e-01, 1.767111740534608e-01, 2.113429529554800e-01,
- 2.487686144599148e-01, 2.887011017469859e-01, 3.308238711499938e-01,
- 3.748145444067251e-01, 4.203080130472308e-01, 4.669049179648736e-01,
- 5.141853413578332e-01, 5.617100406669413e-01, 6.090263461524341e-01,
- 6.556710162134097e-01, 7.012183842298189e-01, 7.452406787622362e-01,
- 7.873692060484326e-01, 8.272238334368036e-01, 8.645136750188277e-01,
- 8.989774146126214e-01, 9.304075179845523e-01, 9.585999373974852e-01,
- 9.834477193784226e-01, 1.004882833289021e+00, 1.022853807278541e+00,
- 1.037404947967044e+00, 1.048597914202596e+00, 1.056561843427440e+00,
- 1.061493706243562e+00, 1.063625783716980e+00, 1.063259727973876e+00,
- 1.060745048351166e+00, 1.056435897894500e+00, 1.050695001011264e+00,
- 1.043924345068839e+00, 1.036477246028582e+00, 1.028728673666003e+00,
- 1.021064859918030e+00, 1.014006582262175e+00, 1.007274550102931e+00,
- 1.001722497437142e+00, 9.973095916665831e-01, 9.939851582601669e-01,
- 9.916833348089591e-01, 9.903253250249126e-01, 9.898226125376152e-01,
- 9.900747339893667e-01, 9.909753143689592e-01, 9.924128512256524e-01,
- 9.942731493578623e-01, 9.964391574315900e-01, 9.987916157534086e-01,
- 1.001209846205687e+00, 1.003573567479612e+00, 1.005759836364722e+00,
- 1.007645153692818e+00, 1.009106872290545e+00, 1.010024764464639e+00,
- 1.010282031682720e+00, 1.009769188700535e+00, 1.008386412173240e+00,
- 1.006051238984656e+00, 1.002697666156926e+00, 9.982804644584213e-01,
- 9.927779867939798e-01, 9.861868921689572e-01, 9.776341643922554e-01,
- 9.674472695701162e-01, 9.551297254161167e-01, 9.403898774115922e-01,
- 9.229592799642977e-01, 9.026073499372684e-01, 8.792026885629480e-01,
- 8.526417497265664e-01, 8.228812716163106e-01, 7.899717151715774e-01,
- 7.540303276706357e-01, 7.152557417328465e-01, 6.739369112409073e-01,
- 6.304147162292445e-01, 5.850788579084674e-01, 5.383985182966198e-01,
- 4.908337531732809e-01, 4.428858232573716e-01, 3.950910240537553e-01,
- 3.480043431985102e-01, 3.021967102409465e-01, 2.582274305805284e-01,
- 2.166414164389013e-01, 1.779221215201146e-01, 1.424805471287674e-01,
- 1.106521943353717e-01, 8.269959669528287e-02, 5.883345162013132e-02,
- 3.920308484545646e-02, 2.386291074479415e-02, 1.269762234246248e-02,
- 5.356653610215987e-03, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00};
-
-// Section 3.7.3.2.2 w_7.5_120 (d09r04_*implementorComments*)
-double w_N120_7p5ms[240] = {
- 2.208248743046650e-03, 3.810144195090351e-03, 5.915524734289813e-03,
- 8.583614568030036e-03, 1.187597226083452e-02, 1.583353014097089e-02,
- 2.049186515516006e-02, 2.588835928921542e-02, 3.204158944817544e-02,
- 3.896167212395468e-02, 4.667421691393490e-02, 5.518493372761350e-02,
- 6.450383844383757e-02, 7.464110714806732e-02, 8.560001618878993e-02,
- 9.738467025048170e-02, 1.099936025389733e-01, 1.234192774722812e-01,
- 1.376554565476283e-01, 1.526904374639564e-01, 1.685133626404965e-01,
- 1.850931046131430e-01, 2.024104194879864e-01, 2.204503651331880e-01,
- 2.391679406203077e-01, 2.585261682883327e-01, 2.784985387736362e-01,
- 2.990384315995911e-01, 3.201048623655521e-01, 3.416586222430363e-01,
- 3.636600340252121e-01, 3.860626951895035e-01, 4.088152724594432e-01,
- 4.318710458458660e-01, 4.551769877048139e-01, 4.786765926352632e-01,
- 5.023248131381035e-01, 5.260609162248473e-01, 5.498312828850233e-01,
- 5.735768827770059e-01, 5.972413384410342e-01, 6.207702424193973e-01,
- 6.440996624336124e-01, 6.671763816763950e-01, 6.899588537658654e-01,
- 7.123799800931302e-01, 7.343963718694788e-01, 7.559666880505324e-01,
- 7.770369811015168e-01, 7.975581136897942e-01, 8.174908555311138e-01,
- 8.367969496408532e-01, 8.554473095679163e-01, 8.734007983991156e-01,
- 8.906357189698083e-01, 9.071287701238782e-01, 9.228487835702877e-01,
- 9.377633225341820e-01, 9.518602062527468e-01, 9.651306001536289e-01,
- 9.775565405467248e-01, 9.891262086779957e-01, 9.998469191683163e-01,
- 1.009700729703874e+00, 1.018682286908352e+00, 1.026814550859190e+00,
- 1.034089812751720e+00, 1.040511956629397e+00, 1.046108368522362e+00,
- 1.050885649534276e+00, 1.054862887578656e+00, 1.058072205849552e+00,
- 1.060534138670111e+00, 1.062276617517642e+00, 1.063338150260194e+00,
- 1.063755566766962e+00, 1.063566320618061e+00, 1.062821557530121e+00,
- 1.061559958917576e+00, 1.059817091581481e+00, 1.057658760384513e+00,
- 1.055120057365395e+00, 1.052239850719546e+00, 1.049087785713381e+00,
- 1.045698595146235e+00, 1.042108306824389e+00, 1.038380985588667e+00,
- 1.034552762539362e+00, 1.030671997181282e+00, 1.026791666942681e+00,
- 1.022955584022344e+00, 1.019207332137853e+00, 1.015872887197225e+00,
- 1.012210174593533e+00, 1.008845591036958e+00, 1.005778512486221e+00,
- 1.003002618498964e+00, 1.000514601809148e+00, 9.983092287560527e-01,
- 9.963786013745719e-01, 9.947181322797367e-01, 9.933162157118496e-01,
- 9.921669569649387e-01, 9.912586027088507e-01, 9.905811038723256e-01,
- 9.901231181863754e-01, 9.898737119947000e-01, 9.898187066647253e-01,
- 9.899468001787191e-01, 9.902431753677082e-01, 9.906955635514434e-01,
- 9.912885401035934e-01, 9.920094690635668e-01, 9.928426927501408e-01,
- 9.937750666306635e-01, 9.947903979828719e-01, 9.958755336221258e-01,
- 9.970143670156726e-01, 9.981928706842119e-01, 9.993945064762333e-01,
- 1.000605860368296e+00, 1.001810400944408e+00, 1.002994573682287e+00,
- 1.004141548053574e+00, 1.005236884099094e+00, 1.006263925890636e+00,
- 1.007208903587772e+00, 1.008054893814649e+00, 1.008788016348394e+00,
- 1.009391822060050e+00, 1.009852958217732e+00, 1.010155293011166e+00,
- 1.010286018304889e+00, 1.010229878703309e+00, 1.009975407736885e+00,
- 1.009508455280294e+00, 1.008818483155921e+00, 1.007894884001199e+00,
- 1.006728757854175e+00, 1.005309913983530e+00, 1.003634560818982e+00,
- 1.001693634792953e+00, 9.994856628696702e-01, 9.970063702291652e-01,
- 9.942546868773952e-01, 9.912319673936767e-01, 9.879371153343368e-01,
- 9.843751246861034e-01, 9.798909633127684e-01, 9.752698788428587e-01,
- 9.701804980040253e-01, 9.645800268203278e-01, 9.584255335155275e-01,
- 9.516840138455831e-01, 9.443202322315050e-01, 9.362906241698766e-01,
- 9.275805069442316e-01, 9.181534137230351e-01, 9.079765240138057e-01,
- 8.970500584793123e-01, 8.853513603848177e-01, 8.728579265043998e-01,
- 8.595798186504622e-01, 8.455026150386550e-01, 8.306199433014801e-01,
- 8.149466481575340e-01, 7.984893775294407e-01, 7.812624496601451e-01,
- 7.632917692550881e-01, 7.445908434203883e-01, 7.251992870809165e-01,
- 7.051536683608545e-01, 6.844905446038185e-01, 6.632452099313783e-01,
- 6.414771616618185e-01, 6.192353336355413e-01, 5.965591325427860e-01,
- 5.735199893648143e-01, 5.501738510234542e-01, 5.265685382300127e-01,
- 5.027811586638018e-01, 4.788608890561979e-01, 4.548778943490807e-01,
- 4.308981228989757e-01, 4.069939642056274e-01, 3.832340305827807e-01,
- 3.596800983344559e-01, 3.364081000913040e-01, 3.134964181526467e-01,
- 2.910105654938709e-01, 2.690195851087463e-01, 2.475843475618672e-01,
- 2.267884333851992e-01, 2.066777706538489e-01, 1.873103432384193e-01,
- 1.687396441250691e-01, 1.510123820588979e-01, 1.341718422797088e-01,
- 1.182546623256353e-01, 1.032907339774596e-01, 8.931173602725516e-02,
- 7.634297866041775e-02, 6.440772914585903e-02, 5.352437147393933e-02,
- 4.370844528199230e-02, 3.496670991534089e-02, 2.729846292648297e-02,
- 2.068958080348781e-02, 1.511251252352759e-02, 1.052287538118900e-02,
- 6.855473143120779e-03, 4.023511190940974e-03, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00};
-
-// Section 3.7.3.2.3 w_7.5_180 (d09r04_*implementorComments*)
-double w_N180_7p5ms[360] = {
- 1.970849076512990e-03, 2.950608593187313e-03, 4.124477213467950e-03,
- 5.526886639437362e-03, 7.175411316438510e-03, 9.087577304291669e-03,
- 1.128191051703656e-02, 1.376953735371754e-02, 1.656002661605294e-02,
- 1.966508945492317e-02, 2.309535564877266e-02, 2.686128938982976e-02,
- 3.096325597431720e-02, 3.540362298325999e-02, 4.019156101100901e-02,
- 4.533314033337320e-02, 5.082893035710152e-02, 5.668154478534839e-02,
- 6.289353044640154e-02, 6.946962925951473e-02, 7.641063136809326e-02,
- 8.371600156519982e-02, 9.138842778133426e-02, 9.942940076792395e-02,
- 1.078347249723074e-01, 1.166045748296231e-01, 1.257365027864348e-01,
- 1.352268113395951e-01, 1.450735459839195e-01, 1.552738186648721e-01,
- 1.658221942341435e-01, 1.767111740534608e-01, 1.879287758848813e-01,
- 1.994731798188807e-01, 2.113429529554800e-01, 2.235245540318082e-01,
- 2.360030996517997e-01, 2.487686144599148e-01, 2.618138107489893e-01,
- 2.751291608544314e-01, 2.887011017469859e-01, 3.025140336309949e-01,
- 3.165588052366450e-01, 3.308238711499938e-01, 3.452955666730954e-01,
- 3.599639915662127e-01, 3.748145444067251e-01, 3.898318165532388e-01,
- 4.050010096015846e-01, 4.203080130472308e-01, 4.357395152859960e-01,
- 4.512778173547499e-01, 4.669049179648736e-01, 4.826090405673480e-01,
- 4.983754662664123e-01, 5.141853413578332e-01, 5.300214783136831e-01,
- 5.458693517886994e-01, 5.617100406669413e-01, 5.775281514417204e-01,
- 5.933046964262578e-01, 6.090263461524341e-01, 6.246741889386914e-01,
- 6.402275547146322e-01, 6.556710162134097e-01, 6.709959346439072e-01,
- 6.861845587972498e-01, 7.012183842298189e-01, 7.160784485622184e-01,
- 7.307560841550591e-01, 7.452406787622362e-01, 7.595151215738793e-01,
- 7.735619554086122e-01, 7.873692060484326e-01, 8.009231377307978e-01,
- 8.142113863131932e-01, 8.272238334368036e-01, 8.399523741938065e-01,
- 8.523861023610134e-01, 8.645136750188277e-01, 8.763240788355384e-01,
- 8.878142883924764e-01, 8.989774146126214e-01, 9.098033189281092e-01,
- 9.202843119253094e-01, 9.304075179845523e-01, 9.401696522166354e-01,
- 9.495677949302647e-01, 9.585999373974852e-01, 9.672602600117832e-01,
- 9.755451659417252e-01, 9.834477193784226e-01, 9.909719572606611e-01,
- 9.981192686440387e-01, 1.004882833289021e+00, 1.011257731140136e+00,
- 1.017244362189382e+00, 1.022853807278541e+00, 1.028087338709125e+00,
- 1.032937063258800e+00, 1.037404947967044e+00, 1.041501641198980e+00,
- 1.045232355730946e+00, 1.048597914202596e+00, 1.051603395002874e+00,
- 1.054255050268478e+00, 1.056561843427440e+00, 1.058534002822506e+00,
- 1.060174135407872e+00, 1.061493706243562e+00, 1.062499430330238e+00,
- 1.063205771472337e+00, 1.063625783716980e+00, 1.063764865344437e+00,
- 1.063637778334477e+00, 1.063259727973876e+00, 1.062646953245063e+00,
- 1.061804962699513e+00, 1.060745048351166e+00, 1.059484915739590e+00,
- 1.058045332777575e+00, 1.056435897894500e+00, 1.054662178717384e+00,
- 1.052740474459255e+00, 1.050695001011264e+00, 1.048538935354313e+00,
- 1.046278982648917e+00, 1.043924345068839e+00, 1.041495397384132e+00,
- 1.039010026880522e+00, 1.036477246028582e+00, 1.033907928361672e+00,
- 1.031319893754215e+00, 1.028728673666003e+00, 1.026148319362665e+00,
- 1.023589880840269e+00, 1.021064859918030e+00, 1.018562619376553e+00,
- 1.016557703375972e+00, 1.014006582262175e+00, 1.011629525863078e+00,
- 1.009385901800645e+00, 1.007274550102931e+00, 1.005296164582239e+00,
- 1.003445259887302e+00, 1.001722497437142e+00, 1.000127924463537e+00,
- 9.986575334669062e-01, 9.973095916665831e-01, 9.960835710929218e-01,
- 9.949765689814285e-01, 9.939851582601669e-01, 9.931075300522219e-01,
- 9.923413052310536e-01, 9.916833348089591e-01, 9.911300696314259e-01,
- 9.906783251641723e-01, 9.903253250249126e-01, 9.900675621816006e-01,
- 9.899012818722897e-01, 9.898226125376152e-01, 9.898278454016073e-01,
- 9.899132411259368e-01, 9.900747339893667e-01, 9.903082558387314e-01,
- 9.906098517881138e-01, 9.909753143689592e-01, 9.914003304461825e-01,
- 9.918809661701072e-01, 9.924128512256524e-01, 9.929917790758115e-01,
- 9.936133813858116e-01, 9.942731493578623e-01, 9.949669577858075e-01,
- 9.956903701113655e-01, 9.964391574315900e-01, 9.972085721948355e-01,
- 9.979942749676792e-01, 9.987916157534086e-01, 9.995960619759856e-01,
- 1.000404101255877e+00, 1.001209846205687e+00, 1.002009756050340e+00,
- 1.002799241686241e+00, 1.003573567479612e+00, 1.004328283187225e+00,
- 1.005058501867633e+00, 1.005759836364722e+00, 1.006427669689071e+00,
- 1.007057682723931e+00, 1.007645153692818e+00, 1.008185492117307e+00,
- 1.008674265369618e+00, 1.009106872290545e+00, 1.009479158919060e+00,
- 1.009786593319936e+00, 1.010024764464639e+00, 1.010189538289831e+00,
- 1.010276690684798e+00, 1.010282031682720e+00, 1.010201742651156e+00,
- 1.010032080837507e+00, 1.009769188700535e+00, 1.009409386073207e+00,
- 1.008949310126241e+00, 1.008386412173240e+00, 1.007717803066923e+00,
- 1.006940305796912e+00, 1.006051238984656e+00, 1.005048793283357e+00,
- 1.003931827630468e+00, 1.002697666156926e+00, 1.001344271172154e+00,
- 9.998720918990379e-01, 9.982804644584213e-01, 9.965665691741982e-01,
- 9.947317370056415e-01, 9.927779867939798e-01, 9.907013741881066e-01,
- 9.885041652445283e-01, 9.861868921689572e-01, 9.837119886839835e-01,
- 9.805846431095010e-01, 9.776341643922554e-01, 9.744550331507363e-01,
- 9.710629155613092e-01, 9.674472695701162e-01, 9.635939262874074e-01,
- 9.594913983473223e-01, 9.551297254161167e-01, 9.505013259120755e-01,
- 9.455928103144016e-01, 9.403898774115922e-01, 9.348867604141315e-01,
- 9.290805587106350e-01, 9.229592799642976e-01, 9.165095791928667e-01,
- 9.097244560733702e-01, 9.026073499372684e-01, 8.951550837577193e-01,
- 8.873561542082500e-01, 8.792026885629480e-01, 8.706996978416294e-01,
- 8.618474244579353e-01, 8.526417497265664e-01, 8.430778332415034e-01,
- 8.331549046805315e-01, 8.228812716163106e-01, 8.122575969197091e-01,
- 8.012854392434710e-01, 7.899717151715774e-01, 7.783181771724644e-01,
- 7.663377104116385e-01, 7.540303276706357e-01, 7.414079909457567e-01,
- 7.284775008035390e-01, 7.152557417328465e-01, 7.017517394571592e-01,
- 6.879756318118113e-01, 6.739369112409073e-01, 6.596525732013095e-01,
- 6.451394890668392e-01, 6.304147162292445e-01, 6.154836219271654e-01,
- 6.003658519413984e-01, 5.850788579084674e-01, 5.696495364564049e-01,
- 5.540848098312343e-01, 5.383985182966198e-01, 5.226147377537511e-01,
- 5.067568049662954e-01, 4.908337531732726e-01, 4.748660326525270e-01,
- 4.588765658108130e-01, 4.428858232573716e-01, 4.269065392300330e-01,
- 4.109709733914872e-01, 3.950910240537540e-01, 3.792913270170828e-01,
- 3.635874169858631e-01, 3.480043431985094e-01, 3.325632006175457e-01,
- 3.172874848823412e-01, 3.021967102409465e-01, 2.873094025754711e-01,
- 2.726439916003860e-01, 2.582274305805277e-01, 2.440728561740129e-01,
- 2.302089773823469e-01, 2.166414164389010e-01, 2.033984806897052e-01,
- 1.904861615463941e-01, 1.779221215201146e-01, 1.657266744835887e-01,
- 1.539063966799855e-01, 1.424805471287671e-01, 1.314539801011583e-01,
- 1.208417782380949e-01, 1.106521943353716e-01, 1.008917341936222e-01,
- 9.157188508647542e-02, 8.269959669528287e-02, 7.428155288862677e-02,
- 6.632423815331720e-02, 5.883345162013123e-02, 5.181406762377953e-02,
- 4.526983455651076e-02, 3.920308484545643e-02, 3.361441594214110e-02,
- 2.850233081562859e-02, 2.386291074479415e-02, 1.968942265531783e-02,
- 1.597205270240860e-02, 1.269762234246247e-02, 9.849377394464552e-03,
- 7.407244632998355e-03, 5.356653610215985e-03, 3.832265518746914e-03,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00};
-
-// Section 3.7.3.2.4 w_7.5_240 (d09r04_*implementorComments*)
-double w_N240_7p5ms[480] = {
- 1.848330370601890e-03, 2.564818394430541e-03, 3.367621175255762e-03,
- 4.287366172947020e-03, 5.338301429131479e-03, 6.526792229804446e-03,
- 7.861125872744963e-03, 9.346281793294168e-03, 1.099168677073023e-02,
- 1.280111724327587e-02, 1.478059105262588e-02, 1.693070430750747e-02,
- 1.925923070409017e-02, 2.176969372101092e-02, 2.446859826144651e-02,
- 2.735565427385896e-02, 3.043192302576378e-02, 3.369804639006632e-02,
- 3.715835772551574e-02, 4.081481795207546e-02, 4.467080684234739e-02,
- 4.872629952625619e-02, 5.298206325441551e-02, 5.743824696664848e-02,
- 6.209685798752235e-02, 6.696097666085293e-02, 7.202983636789818e-02,
- 7.730391464771366e-02, 8.278255740953620e-02, 8.846821015931731e-02,
- 9.436075664518449e-02, 1.004602720036002e-01, 1.067638237504515e-01,
- 1.132736794406103e-01, 1.199864202730101e-01, 1.269035206805856e-01,
- 1.340208531277774e-01, 1.413395568701277e-01, 1.488572112889720e-01,
- 1.565736853381255e-01, 1.644846220563571e-01, 1.725890765381433e-01,
- 1.808790898204713e-01, 1.893543196006846e-01, 1.980122435284018e-01,
- 2.068541409946420e-01, 2.158753187570538e-01, 2.250686723708130e-01,
- 2.344274072499690e-01, 2.439483137105153e-01, 2.536279928378056e-01,
- 2.634640609879333e-01, 2.734504944781370e-01, 2.835821889865098e-01,
- 2.938534694786572e-01, 3.042573734615632e-01, 3.147909140113310e-01,
- 3.254491234269504e-01, 3.362274096618026e-01, 3.471187602907065e-01,
- 3.581201769604495e-01, 3.692246633783371e-01, 3.804277928712796e-01,
- 3.917200227416179e-01, 4.030970221548365e-01, 4.145519552168687e-01,
- 4.260817186124239e-01, 4.376763184816823e-01, 4.493301956572350e-01,
- 4.610348550393067e-01, 4.727860432828289e-01, 4.845767771787368e-01,
- 4.964017067665196e-01, 5.082524575564947e-01, 5.201220784839651e-01,
- 5.320020770005417e-01, 5.438880897441558e-01, 5.557716011811357e-01,
- 5.676457387746829e-01, 5.795027863150121e-01, 5.913350345927856e-01,
- 6.031383674734400e-01, 6.149041716859808e-01, 6.266239411056014e-01,
- 6.382888344252021e-01, 6.498933747767719e-01, 6.614323601501731e-01,
- 6.729025139063478e-01, 6.842937498334491e-01, 6.956004595358826e-01,
- 7.068117836489756e-01, 7.179234245192330e-01, 7.289313857272890e-01,
- 7.398327727973596e-01, 7.506189823719328e-01, 7.612840534177552e-01,
- 7.718189187016244e-01, 7.822209919639922e-01, 7.924813304551203e-01,
- 8.025994477230463e-01, 8.125652295019083e-01, 8.223771289200885e-01,
- 8.320305183749199e-01, 8.415232076745133e-01, 8.508483129483138e-01,
- 8.600024117819522e-01, 8.689798808251054e-01, 8.777783467294870e-01,
- 8.863959039558345e-01, 8.948294207910807e-01, 9.030776256602892e-01,
- 9.111326521556180e-01, 9.189935853649371e-01, 9.266529369336567e-01,
- 9.341114204165168e-01, 9.413643442928993e-01, 9.484129673709889e-01,
- 9.552556295973936e-01, 9.618920131378678e-01, 9.683163629086772e-01,
- 9.745301563621191e-01, 9.805283381417256e-01, 9.863139277672938e-01,
- 9.918860486198928e-01, 9.972463447664014e-01, 1.002391896644578e+00,
- 1.007319464375827e+00, 1.012027073435850e+00, 1.016516541512393e+00,
- 1.020794302688699e+00, 1.024860815794490e+00, 1.028714705809749e+00,
- 1.032351702719174e+00, 1.035773750472822e+00, 1.038984315074006e+00,
- 1.041987855398911e+00, 1.044785643573356e+00, 1.047378184121997e+00,
- 1.049767431495211e+00, 1.051954045543143e+00, 1.053942898562160e+00,
- 1.055734631473796e+00, 1.057341767323983e+00, 1.058757264938716e+00,
- 1.059986744473714e+00, 1.061036716870687e+00, 1.061906510844496e+00,
- 1.062603694906377e+00, 1.063132893292572e+00, 1.063502373941053e+00,
- 1.063709808061891e+00, 1.063763223461893e+00, 1.063667646046172e+00,
- 1.063430118187021e+00, 1.063056564385666e+00, 1.062554210368898e+00,
- 1.061922346664364e+00, 1.061167017783231e+00, 1.060294689234573e+00,
- 1.059314689493745e+00, 1.058234647303768e+00, 1.057058907527535e+00,
- 1.055789482473656e+00, 1.054429786866560e+00, 1.052987925902714e+00,
- 1.051475051645344e+00, 1.049899300533228e+00, 1.048262129495776e+00,
- 1.046566906015578e+00, 1.044816992642391e+00, 1.043021249196200e+00,
- 1.041187680907488e+00, 1.039323391025476e+00, 1.037431684165083e+00,
- 1.035517573311265e+00, 1.033585105989712e+00, 1.031643708543028e+00,
- 1.029699545977279e+00, 1.027759438517856e+00, 1.025827187037112e+00,
- 1.023907910886626e+00, 1.022008050685529e+00, 1.020139101207016e+00,
- 1.018263100813380e+00, 1.016879010849981e+00, 1.014921948187593e+00,
- 1.013096623369458e+00, 1.011342052440818e+00, 1.009659122960534e+00,
- 1.008050363886717e+00, 1.006517540250988e+00, 1.005057992517306e+00,
- 1.003669560904293e+00, 1.002353273092562e+00, 1.001109808447114e+00,
- 9.999375230640204e-01, 9.988345237783536e-01, 9.978006059268592e-01,
- 9.968357558473706e-01, 9.959388811568640e-01, 9.951084589555501e-01,
- 9.943434110903315e-01, 9.936429211981983e-01, 9.930058324270904e-01,
- 9.924309837770386e-01, 9.919174926403282e-01, 9.914638980147298e-01,
- 9.910682139572967e-01, 9.907292184488009e-01, 9.904462245644213e-01,
- 9.902178185518503e-01, 9.900419630667118e-01, 9.899170852600004e-01,
- 9.898419746989491e-01, 9.898150482937847e-01, 9.898343291371600e-01,
- 9.898982107247224e-01, 9.900054030605746e-01, 9.901541892638673e-01,
- 9.903424269195302e-01, 9.905684589910844e-01, 9.908309527413479e-01,
- 9.911280379271901e-01, 9.914575656842904e-01, 9.918178809274675e-01,
- 9.922075589719793e-01, 9.926247572992801e-01, 9.930673584123647e-01,
- 9.935333982795475e-01, 9.940214100660039e-01, 9.945296851337717e-01,
- 9.950559636181178e-01, 9.955983505434736e-01, 9.961555801042186e-01,
- 9.967256267769223e-01, 9.973060922083319e-01, 9.978952138542876e-01,
- 9.984914406319209e-01, 9.990928899877792e-01, 9.996970625756828e-01,
- 1.000303029223210e+00, 1.000907933607887e+00, 1.001510838557739e+00,
- 1.002109225614564e+00, 1.002701184533730e+00, 1.003285129964668e+00,
- 1.003859256498246e+00, 1.004421109631332e+00, 1.004968601327613e+00,
- 1.005500403806944e+00, 1.006014548452834e+00, 1.006508690831783e+00,
- 1.006981038626341e+00, 1.007430041056790e+00, 1.007853640055005e+00,
- 1.008249618432853e+00, 1.008616036239346e+00, 1.008951378362138e+00,
- 1.009253896674588e+00, 1.009521341935844e+00, 1.009751751331617e+00,
- 1.009943714668776e+00, 1.010095497366507e+00, 1.010204876790192e+00,
- 1.010270073045154e+00, 1.010289752336835e+00, 1.010262269696272e+00,
- 1.010185615431975e+00, 1.010058196828792e+00, 1.009878817836722e+00,
- 1.009645930489341e+00, 1.009357533197330e+00, 1.009012281815637e+00,
- 1.008609594360786e+00, 1.008148366592626e+00, 1.007626743165711e+00,
- 1.007043430506158e+00, 1.006397749801444e+00, 1.005688767931258e+00,
- 1.004915585834316e+00, 1.004077678781271e+00, 1.003174288376062e+00,
- 1.002204242070086e+00, 1.001166836141424e+00, 1.000062480839591e+00,
- 9.988914218622672e-01, 9.976522518001048e-01, 9.963438555404762e-01,
- 9.949674620221296e-01, 9.935246630184282e-01, 9.920139269077016e-01,
- 9.904332831340030e-01, 9.887851470099116e-01, 9.870726808604894e-01,
- 9.852974426119764e-01, 9.834011611313795e-01, 9.809494177655508e-01,
- 9.787827290446353e-01, 9.764682383490441e-01, 9.740428502007106e-01,
- 9.714988482797869e-01, 9.688299679017578e-01, 9.660309739278938e-01,
- 9.630951038651144e-01, 9.600181976898812e-01, 9.567957384046786e-01,
- 9.534262666962353e-01, 9.499034823039632e-01, 9.462221151684139e-01,
- 9.423758195026390e-01, 9.383617015143452e-01, 9.341777978631194e-01,
- 9.298231239088762e-01, 9.252923195046721e-01, 9.205801200661107e-01,
- 9.156797929682001e-01, 9.105906042938267e-01, 9.053150301587091e-01,
- 8.998527561071954e-01, 8.941994971184931e-01, 8.883501524279332e-01,
- 8.823016313374981e-01, 8.760548741525249e-01, 8.696123849407055e-01,
- 8.629727993296973e-01, 8.561351975749198e-01, 8.490981786073120e-01,
- 8.418570243421116e-01, 8.344140550191105e-01, 8.267746168752393e-01,
- 8.189392440268611e-01, 8.109048914872936e-01, 8.026753184506191e-01,
- 7.942537505258295e-01, 7.856416615920516e-01, 7.768386086617421e-01,
- 7.678531932560713e-01, 7.586851806705738e-01, 7.493306577133620e-01,
- 7.398091711550503e-01, 7.301099443577747e-01, 7.202477806201014e-01,
- 7.102241609901638e-01, 7.000443258461506e-01, 6.897118895404929e-01,
- 6.792311541046628e-01, 6.686081789247391e-01, 6.578509967842496e-01,
- 6.469657182336516e-01, 6.359596166227444e-01, 6.248403358991607e-01,
- 6.136035026791002e-01, 6.022650906421884e-01, 5.908290833732823e-01,
- 5.793094079430561e-01, 5.677111240020907e-01, 5.560374156751429e-01,
- 5.442936643492620e-01, 5.324897680536480e-01, 5.206360841136255e-01,
- 5.087432727680400e-01, 4.968111660413653e-01, 4.848498807089364e-01,
- 4.728681073650310e-01, 4.608759183794885e-01, 4.488810806327018e-01,
- 4.368910387727512e-01, 4.249120223507826e-01, 4.129606031641687e-01,
- 4.010358962877044e-01, 3.891578667449375e-01, 3.773221988116735e-01,
- 3.655437668630012e-01, 3.538323564250667e-01, 3.421961154339837e-01,
- 3.306448201086834e-01, 3.191875589898712e-01, 3.078333093391901e-01,
- 2.965881816516454e-01, 2.854637165360221e-01, 2.744624088577634e-01,
- 2.636095844768899e-01, 2.528831011433226e-01, 2.423234889711821e-01,
- 2.319257462841697e-01, 2.216908373695833e-01, 2.116380576950307e-01,
- 2.017669202945304e-01, 1.920822358183417e-01, 1.825891600132626e-01,
- 1.733059967407588e-01, 1.642292000450303e-01, 1.553626542479246e-01,
- 1.467170785977411e-01, 1.382993914151456e-01, 1.301050780767305e-01,
- 1.221453099291547e-01, 1.144234581921691e-01, 1.069410759923033e-01,
- 9.970258934460623e-02, 9.271242833748693e-02, 8.597374270620267e-02,
- 7.948933111952143e-02, 7.326165794605345e-02, 6.729341023108891e-02,
- 6.158740810076327e-02, 5.614580025932222e-02, 5.097007470356519e-02,
- 4.606170471457775e-02, 4.142201169265410e-02, 3.705141887506228e-02,
- 3.294946662279392e-02, 2.911533269413120e-02, 2.554764013238235e-02,
- 2.224377112828603e-02, 1.920006589797908e-02, 1.641222045266977e-02,
- 1.387476111201306e-02, 1.158063529909875e-02, 9.522136642215920e-03,
- 7.691373795814687e-03, 6.072078331193099e-03, 4.625812168742676e-03,
- 3.606851641625968e-03, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00};
-
-// Section 3.7.3.2.5 w_7.5_360 (d09r04_*implementorComments*)
-double w_N360_7p5ms[720] = {
- 1.721526681611966e-03, 2.208248743046650e-03, 2.689017522595345e-03,
- 3.226133417706577e-03, 3.810144195090351e-03, 4.453719317184182e-03,
- 5.153692399681317e-03, 5.915524734289813e-03, 6.738691584410875e-03,
- 7.628618406907552e-03, 8.583614568030036e-03, 9.609384374613759e-03,
- 1.070607532160120e-02, 1.187597226083452e-02, 1.311901297315944e-02,
- 1.443901078588673e-02, 1.583353014097089e-02, 1.730630810758647e-02,
- 1.885847112173313e-02, 2.049186515516006e-02, 2.220614764140174e-02,
- 2.400571662419946e-02, 2.588835928921542e-02, 2.785523259150068e-02,
- 2.990591454016386e-02, 3.204158944817544e-02, 3.426100132985917e-02,
- 3.656809727321165e-02, 3.896167212395468e-02, 4.144358235567028e-02,
- 4.401407955156517e-02, 4.667421691393490e-02, 4.942146249896087e-02,
- 5.225884889914327e-02, 5.518493372761350e-02, 5.820051428449914e-02,
- 6.130598448769178e-02, 6.450383844383757e-02, 6.779139227807153e-02,
- 7.117078328947134e-02, 7.464110714806732e-02, 7.820280530933912e-02,
- 8.185495207937329e-02, 8.560001618878993e-02, 8.943576174662307e-02,
- 9.336425891679158e-02, 9.738467025048170e-02, 1.014967178422148e-01,
- 1.056987601379146e-01, 1.099936025389733e-01, 1.143782870006880e-01,
- 1.188535076446910e-01, 1.234192774722812e-01, 1.280759966861818e-01,
- 1.328205805921621e-01, 1.376554565476283e-01, 1.425786478649834e-01,
- 1.475905216894996e-01, 1.526904374639564e-01, 1.578788527293271e-01,
- 1.631525285166384e-01, 1.685133626404965e-01, 1.739579689655531e-01,
- 1.794847365410843e-01, 1.850931046131430e-01, 1.907848350801405e-01,
- 1.965564972779563e-01, 2.024104194879864e-01, 2.083454334275949e-01,
- 2.143598248322309e-01, 2.204503651331880e-01, 2.266172963796335e-01,
- 2.328562792793315e-01, 2.391679406203077e-01, 2.455506417347264e-01,
- 2.520039508016560e-01, 2.585261682883327e-01, 2.651184076263592e-01,
- 2.717759113203786e-01, 2.784985387736362e-01, 2.852846062288917e-01,
- 2.921324591263930e-01, 2.990384315995911e-01, 3.060042559686472e-01,
- 3.130265290443111e-01, 3.201048623655521e-01, 3.272373243719107e-01,
- 3.344232095441687e-01, 3.416586222430363e-01, 3.489449761645191e-01,
- 3.562792519116003e-01, 3.636600340252121e-01, 3.710851463600319e-01,
- 3.785543267164805e-01, 3.860626951895035e-01, 3.936105536140438e-01,
- 4.011952247532815e-01, 4.088152724594432e-01, 4.164684603494585e-01,
- 4.241554113955093e-01, 4.318710458458660e-01, 4.396147439144481e-01,
- 4.473840194903529e-01, 4.551769877048139e-01, 4.629901375019677e-01,
- 4.708246187885389e-01, 4.786765926352632e-01, 4.865454331135768e-01,
- 4.944287144003222e-01, 5.023248131381035e-01, 5.102294714645887e-01,
- 5.181429265558146e-01, 5.260609162248473e-01, 5.339828176544869e-01,
- 5.419068167854945e-01, 5.498312828850233e-01, 5.577512337479950e-01,
- 5.656676362338563e-01, 5.735768827770059e-01, 5.814766655477682e-01,
- 5.893646610908023e-01, 5.972413384410342e-01, 6.051020131945327e-01,
- 6.129461702965266e-01, 6.207702424193973e-01, 6.285720938000074e-01,
- 6.363485261821292e-01, 6.440996624336124e-01, 6.518209733012164e-01,
- 6.595138217057872e-01, 6.671763816763950e-01, 6.748067951703918e-01,
- 6.824007108459023e-01, 6.899588537658654e-01, 6.974757223488888e-01,
- 7.049501447553026e-01, 7.123799800931302e-01, 7.197654340542331e-01,
- 7.271038329243241e-01, 7.343963718694788e-01, 7.416385606661200e-01,
- 7.488296394277816e-01, 7.559666880505324e-01, 7.630492594418218e-01,
- 7.700722734566787e-01, 7.770369811015168e-01, 7.839411079555614e-01,
- 7.907812565704104e-01, 7.975581136897942e-01, 8.042713809653173e-01,
- 8.109149005929875e-01, 8.174908555311138e-01, 8.239970937711972e-01,
- 8.304327850184938e-01, 8.367969496408532e-01, 8.430892979726279e-01,
- 8.493058471422328e-01, 8.554473095679163e-01, 8.615110365133289e-01,
- 8.674962806836773e-01, 8.734007983991156e-01, 8.792275183442975e-01,
- 8.849724383046952e-01, 8.906357189698083e-01, 8.962171727097513e-01,
- 9.017164138681113e-01, 9.071287701238782e-01, 9.124565781610174e-01,
- 9.176972608396821e-01, 9.228487835702877e-01, 9.279099172570797e-01,
- 9.328825964768623e-01, 9.377633225341820e-01, 9.425533559491475e-01,
- 9.472524281763984e-01, 9.518602062527468e-01, 9.563760599307146e-01,
- 9.608006016536426e-01, 9.651306001536289e-01, 9.693666888567923e-01,
- 9.735088121912839e-01, 9.775565405467248e-01, 9.815072260762016e-01,
- 9.853645802900605e-01, 9.891262086779957e-01, 9.927942006806012e-01,
- 9.963675450849775e-01, 9.998469191683163e-01, 1.003228124845146e+00,
- 1.006513411821911e+00, 1.009700729703874e+00, 1.012790289606342e+00,
- 1.015782934360887e+00, 1.018682286908352e+00, 1.021486570410198e+00,
- 1.024197718428813e+00, 1.026814550859190e+00, 1.029335981099974e+00,
- 1.031760429936344e+00, 1.034089812751720e+00, 1.036323258515780e+00,
- 1.038463607653629e+00, 1.040511956629397e+00, 1.042468314695544e+00,
- 1.044333310154580e+00, 1.046108368522362e+00, 1.047790183156567e+00,
- 1.049383335559126e+00, 1.050885649534276e+00, 1.052299234616223e+00,
- 1.053625218490635e+00, 1.054862887578656e+00, 1.056015206502275e+00,
- 1.057087459299065e+00, 1.058072205849552e+00, 1.058975241719203e+00,
- 1.059794467230661e+00, 1.060534138670111e+00, 1.061194118632638e+00,
- 1.061773655564821e+00, 1.062276617517642e+00, 1.062703237255151e+00,
- 1.063055685508735e+00, 1.063338150260194e+00, 1.063547997184066e+00,
- 1.063686067900426e+00, 1.063755566766962e+00, 1.063757434953141e+00,
- 1.063693583520601e+00, 1.063566320618061e+00, 1.063377073891492e+00,
- 1.063127819699189e+00, 1.062821557530121e+00, 1.062457815392427e+00,
- 1.062036342819983e+00, 1.061559958917576e+00, 1.061029510184661e+00,
- 1.060447965083549e+00, 1.059817091581481e+00, 1.059141628118411e+00,
- 1.058421358875364e+00, 1.057658760384513e+00, 1.056853774077034e+00,
- 1.056007614360998e+00, 1.055120057365395e+00, 1.054195045438248e+00,
- 1.053233455551333e+00, 1.052239850719546e+00, 1.051216675517538e+00,
- 1.050166369287038e+00, 1.049087785713381e+00, 1.047983664181190e+00,
- 1.046853337647985e+00, 1.045698595146235e+00, 1.044520564730305e+00,
- 1.043323481681635e+00, 1.042108306824389e+00, 1.040879073476582e+00,
- 1.039636032987793e+00, 1.038380985588667e+00, 1.037114029603682e+00,
- 1.035838134533162e+00, 1.034552762539362e+00, 1.033262000621490e+00,
- 1.031967497567261e+00, 1.030671997181282e+00, 1.029375639312502e+00,
- 1.028082437365047e+00, 1.026791666942681e+00, 1.025506352493464e+00,
- 1.024226550306258e+00, 1.022955584022344e+00, 1.021692989563247e+00,
- 1.020444748460154e+00, 1.019207332137853e+00, 1.017999919156420e+00,
- 1.017160217193961e+00, 1.015872887197225e+00, 1.014617829299498e+00,
- 1.013397380801344e+00, 1.012210174593533e+00, 1.011056516187721e+00,
- 1.009934436494794e+00, 1.008845591036958e+00, 1.007789557609578e+00,
- 1.006767901472734e+00, 1.005778512486221e+00, 1.004821733696763e+00,
- 1.003895920161236e+00, 1.003002618498964e+00, 1.002140907258662e+00,
- 1.001312127031557e+00, 1.000514601809148e+00, 9.997489875663875e-01,
- 9.990134860651736e-01, 9.983092287560527e-01, 9.976349335738018e-01,
- 9.969918851181095e-01, 9.963786013745719e-01, 9.957959823242557e-01,
- 9.952422174315529e-01, 9.947181322797367e-01, 9.942221216035205e-01,
- 9.937553132700969e-01, 9.933162157118496e-01, 9.929058092648040e-01,
- 9.925224215680564e-01, 9.921669569649387e-01, 9.918377038474807e-01,
- 9.915355084098528e-01, 9.912586027088507e-01, 9.910078784250421e-01,
- 9.907817226664765e-01, 9.905811038723256e-01, 9.904043360106435e-01,
- 9.902522665150607e-01, 9.901231181863754e-01, 9.900177259420802e-01,
- 9.899343252516752e-01, 9.898737119947000e-01, 9.898341100636087e-01,
- 9.898163585163330e-01, 9.898187066647253e-01, 9.898419976335596e-01,
- 9.898844376083749e-01, 9.899468001787191e-01, 9.900272871794666e-01,
- 9.901266804330273e-01, 9.902431753677082e-01, 9.903775935673591e-01,
- 9.905281337320039e-01, 9.906955635514434e-01, 9.908780432538649e-01,
- 9.910763016962206e-01, 9.912885401035934e-01, 9.915156019790364e-01,
- 9.917556658638569e-01, 9.920094690635668e-01, 9.922751554325331e-01,
- 9.925534864640656e-01, 9.928426927501408e-01, 9.931435333387140e-01,
- 9.934540796611835e-01, 9.937750666306635e-01, 9.941046890713076e-01,
- 9.944437415635388e-01, 9.947903979828719e-01, 9.951453611435701e-01,
- 9.955067995758305e-01, 9.958755336221258e-01, 9.962496814968456e-01,
- 9.966299185765186e-01, 9.970143670156726e-01, 9.974037994063020e-01,
- 9.977964044701016e-01, 9.981928706842119e-01, 9.985912855613679e-01,
- 9.989924362978263e-01, 9.993945064762333e-01, 9.997982470741876e-01,
- 1.000201793638269e+00, 1.000605860368296e+00, 1.001008579910682e+00,
- 1.001410701714506e+00, 1.001810400944408e+00, 1.002208462087081e+00,
- 1.002602958395831e+00, 1.002994573682287e+00, 1.003381477277237e+00,
- 1.003764436338408e+00, 1.004141548053574e+00, 1.004513480396200e+00,
- 1.004878321344784e+00, 1.005236884099094e+00, 1.005587302935534e+00,
- 1.005930271724399e+00, 1.006263925890636e+00, 1.006589051746658e+00,
- 1.006903802351948e+00, 1.007208903587772e+00, 1.007502380110983e+00,
- 1.007784982346051e+00, 1.008054893814649e+00, 1.008312868199207e+00,
- 1.008556999006399e+00, 1.008788016348394e+00, 1.009004047709048e+00,
- 1.009205932867561e+00, 1.009391822060050e+00, 1.009562440424896e+00,
- 1.009715896739930e+00, 1.009852958217732e+00, 1.009971774079105e+00,
- 1.010073169648632e+00, 1.010155293011166e+00, 1.010218932642345e+00,
- 1.010262246288524e+00, 1.010286018304889e+00, 1.010288415013601e+00,
- 1.010270296641665e+00, 1.010229878703309e+00, 1.010168022758243e+00,
- 1.010082924574326e+00, 1.009975407736885e+00, 1.009843687123529e+00,
- 1.009688632854747e+00, 1.009508455280294e+00, 1.009304044596942e+00,
- 1.009073713509976e+00, 1.008818483155921e+00, 1.008536750845889e+00,
- 1.008229467503460e+00, 1.007894884001199e+00, 1.007533913863759e+00,
- 1.007144877861525e+00, 1.006728757854175e+00, 1.006283927891016e+00,
- 1.005811456284196e+00, 1.005309913983530e+00, 1.004780527277797e+00,
- 1.004221766054862e+00, 1.003634560818982e+00, 1.003017190938855e+00,
- 1.002370673225852e+00, 1.001693634792953e+00, 1.000987488105603e+00,
- 1.000251075456674e+00, 9.994856628696702e-01, 9.986895923896904e-01,
- 9.978636664333774e-01, 9.970063702291652e-01, 9.961191991291183e-01,
- 9.952014038559622e-01, 9.942546868773952e-01, 9.932775951012806e-01,
- 9.922706506028359e-01, 9.912319673936767e-01, 9.901632857185525e-01,
- 9.890643935223216e-01, 9.879371153343368e-01, 9.867797361083076e-01,
- 9.855927730842358e-01, 9.843751246861034e-01, 9.831292878900623e-01,
- 9.813484629113276e-01, 9.798909633127684e-01, 9.784004589849064e-01,
- 9.768604354115724e-01, 9.752698788428587e-01, 9.736273532416118e-01,
- 9.719313409832228e-01, 9.701804980040253e-01, 9.683726519652567e-01,
- 9.665069522597068e-01, 9.645800268203277e-01, 9.625923175883123e-01,
- 9.605409863432730e-01, 9.584255335155275e-01, 9.562443932750193e-01,
- 9.539984159028931e-01, 9.516840138455831e-01, 9.493011853637791e-01,
- 9.468468843298323e-01, 9.443202322315050e-01, 9.417184043233268e-01,
- 9.390425796467096e-01, 9.362906241698766e-01, 9.334640497363101e-01,
- 9.305608538768808e-01, 9.275805069442316e-01, 9.245195917195164e-01,
- 9.213784714413848e-01, 9.181534137230349e-01, 9.148446956130220e-01,
- 9.114516516017124e-01, 9.079765240138057e-01, 9.044175450831859e-01,
- 9.007763077278617e-01, 8.970500584793123e-01, 8.932383978549314e-01,
- 8.893386805647778e-01, 8.853513603848177e-01, 8.812740229566767e-01,
- 8.771096379139661e-01, 8.728579265043998e-01, 8.685195050926551e-01,
- 8.640927964490425e-01, 8.595798186504622e-01, 8.549760065595760e-01,
- 8.502852201263446e-01, 8.455026150386550e-01, 8.406304703204051e-01,
- 8.356679254927833e-01, 8.306199433014801e-01, 8.254820069905587e-01,
- 8.202589087059164e-01, 8.149466481575340e-01, 8.095466959213909e-01,
- 8.040599778581757e-01, 7.984893775294406e-01, 7.928314173180783e-01,
- 7.870906681120101e-01, 7.812624496601451e-01, 7.753539468965313e-01,
- 7.693636129738075e-01, 7.632917692550881e-01, 7.571390164385375e-01,
- 7.509017111797436e-01, 7.445908434203883e-01, 7.382051359832217e-01,
- 7.317380750199757e-01, 7.251992870809165e-01, 7.185882252895927e-01,
- 7.119056866892599e-01, 7.051536683608545e-01, 6.983326341551366e-01,
- 6.914441012238667e-01, 6.844905446038185e-01, 6.774701192768717e-01,
- 6.703883753752553e-01, 6.632452099313783e-01, 6.560457800753937e-01,
- 6.487886269109083e-01, 6.414771616618185e-01, 6.341143226974428e-01,
- 6.267020002885999e-01, 6.192353336355413e-01, 6.117205957668128e-01,
- 6.041616120083719e-01, 5.965591325427860e-01, 5.889144007425270e-01,
- 5.812347834141942e-01, 5.735199893648143e-01, 5.657706158383411e-01,
- 5.579880671567978e-01, 5.501738510234542e-01, 5.423301939386325e-01,
- 5.344607980557825e-01, 5.265685382300127e-01, 5.186563241060174e-01,
- 5.107288126105302e-01, 5.027811586638018e-01, 4.948194909906872e-01,
- 4.868451392486417e-01, 4.788608890561871e-01, 4.708699282370115e-01,
- 4.628751440565413e-01, 4.548778943490807e-01, 4.468825120278060e-01,
- 4.388893249911809e-01, 4.308981228989757e-01, 4.229183223777856e-01,
- 4.149508779761170e-01, 4.069939642056243e-01, 3.990526483957498e-01,
- 3.911346135115557e-01, 3.832340305827807e-01, 3.753546526584436e-01,
- 3.675020596488621e-01, 3.596800983344559e-01, 3.518873119772211e-01,
- 3.441301658282572e-01, 3.364081000913025e-01, 3.287289661673846e-01,
- 3.210905051632958e-01, 3.134964181526467e-01, 3.059515649397201e-01,
- 2.984543187240678e-01, 2.910105654938703e-01, 2.836211093775042e-01,
- 2.762854150573731e-01, 2.690195851087454e-01, 2.618124452057962e-01,
- 2.546592323719683e-01, 2.475843475618672e-01, 2.405786941912602e-01,
- 2.336470086662776e-01, 2.267884333851989e-01, 2.200019917678347e-01,
- 2.133013251703927e-01, 2.066777706538484e-01, 2.001404091043453e-01,
- 1.936836302775967e-01, 1.873103432384193e-01, 1.810273838836248e-01,
- 1.748394760623094e-01, 1.687396441250690e-01, 1.627372734819174e-01,
- 1.568252770506826e-01, 1.510123820588976e-01, 1.452982295367473e-01,
- 1.396874693829809e-01, 1.341718422797088e-01, 1.287625441360194e-01,
- 1.234555620731477e-01, 1.182546623256352e-01, 1.131596767663045e-01,
- 1.081714392735899e-01, 1.032907339774594e-01, 9.852029779063426e-02,
- 9.386000226048140e-02, 8.931173602725516e-02, 8.487521028829931e-02,
- 8.055237373221881e-02, 7.634297866041770e-02, 7.224892456088809e-02,
- 6.826991195487858e-02, 6.440772914585895e-02, 6.066200028414472e-02,
- 5.703437111472432e-02, 5.352437147393933e-02, 5.013346896851077e-02,
- 4.686107896077298e-02, 4.370844528199226e-02, 4.067483652594974e-02,
- 3.776122690656316e-02, 3.496670991534084e-02, 3.229192748331241e-02,
- 2.973576687031024e-02, 2.729846292648297e-02, 2.497871856111264e-02,
- 2.277625418320712e-02, 2.068958080348780e-02, 1.871781693470649e-02,
- 1.685934175287805e-02, 1.511251252352758e-02, 1.347570944951177e-02,
- 1.194627091218482e-02, 1.052287538118900e-02, 9.201309412840026e-03,
- 7.981243163732707e-03, 6.855473143120775e-03, 5.826573343851640e-03,
- 4.878385254226555e-03, 4.023511190940970e-03, 3.154186627586960e-03,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
- 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00};
diff --git a/system/embdrv/lc3_dec/Common/Tables/MdctWindows.hpp b/system/embdrv/lc3_dec/Common/Tables/MdctWindows.hpp
deleted file mode 100644
index 8b6bcc6a5b..0000000000
--- a/system/embdrv/lc3_dec/Common/Tables/MdctWindows.hpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * MdctWindows.cpp
- *
- * 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.
- */
-
-#ifndef MDCT_WINDOWS_H_
-#define MDCT_WINDOWS_H_
-
-// LC3 Specification d09r01.pdf
-// Section 5.7.2
-
-// LC3 Specification d09r04_*implementorComments*
-// Section 3.7.3 Low delay MDCT windows
-// Section 3.7.3.1 10 ms Frame Duration
-
-extern double w_N80[160];
-extern double w_N160[320];
-extern double w_N240[480];
-extern double w_N320[640];
-extern double w_N480[960];
-
-// Section 3.7.3.2 7.5 ms Frame Duration
-
-extern double w_N60_7p5ms[120];
-extern double w_N120_7p5ms[240];
-extern double w_N180_7p5ms[360];
-extern double w_N240_7p5ms[480];
-extern double w_N360_7p5ms[720];
-
-#endif // MDCT_WINDOWS_H_
diff --git a/system/embdrv/lc3_dec/Common/Tables/SnsQuantizationTables.cpp b/system/embdrv/lc3_dec/Common/Tables/SnsQuantizationTables.cpp
deleted file mode 100644
index 55b3462cda..0000000000
--- a/system/embdrv/lc3_dec/Common/Tables/SnsQuantizationTables.cpp
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * SnsQuantizationTables.cpp
- *
- * 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.
- */
-
-// LC3 Specification d09r01.pdf
-// Section 5.7.3 SNS Quantization
-
-// LC3 Specification d09r04_*implementorComments*
-// Section 3.7.4 SNS Quantization
-
-#include "SnsQuantizationTables.hpp"
-
-// LC3 Specification d09r01.pdf; Page 102 of 177
-double LFCB[32][8] = {
- {+2.262833655926780e+00, +8.133112690613385e-01, -5.301934948714359e-01,
- -1.356648359034418e+00, -1.599521765631959e+00, -1.440987684300950e+00,
- -1.143816483058210e+00, -7.552037679090641e-01}, // 0
- {+2.945164791913764e+00, +2.411433179566788e+00, +9.604551064007274e-01,
- -4.432264880769172e-01, -1.229136124255896e+00, -1.555900391181699e+00,
- -1.496886559523759e+00, -1.116899865014692e+00}, // 1
- {-2.186107070099790e+00, -1.971521356752276e+00, -1.787186196810059e+00,
- -1.918658956855768e+00, -1.793991218365963e+00, -1.357384042572884e+00,
- -7.054442793538694e-01, -4.781729447777114e-02}, // 2
- {+6.936882365289195e-01, +9.556098571582197e-01, +5.752307870387333e-01,
- -1.146034194628886e-01, -6.460506374360290e-01, -9.523513704496247e-01,
- -1.074052472261504e+00, -7.580877070949045e-01}, // 3
- {-1.297521323152956e+00, -7.403690571778526e-01, -3.453724836421064e-01,
- -3.132856962479401e-01, -4.029772428244766e-01, -3.720208534652272e-01,
- -7.834141773237381e-02, +9.704413039922949e-02}, // 4
- {+9.146520378306716e-01, +1.742930434352573e+00, +1.909066268599861e+00,
- +1.544084838426651e+00, +1.093449607614550e+00, +6.474795495182776e-01,
- +3.617907524496421e-02, -2.970928071788889e-01}, // 5
- {-2.514288125789621e+00, -2.891752713843728e+00, -2.004506667594338e+00,
- -7.509122739031269e-01, +4.412021049046914e-01, +1.201909876010087e+00,
- +1.327428572572904e+00, +1.220490811409839e+00}, // 6
- {-9.221884048123851e-01, +6.324951414405520e-01, +1.087364312546411e+00,
- +6.086286245358197e-01, +1.311745675473482e-01, -2.961491577437521e-01,
- -2.070135165256287e-01, +1.349249166420795e-01}, // 7
- {+7.903222883692664e-01, +6.284012618761988e-01, +3.931179235404499e-01,
- +4.800077108669007e-01, +4.478151380501427e-01, +2.097342145522343e-01,
- +6.566919964280205e-03, -8.612423420618573e-02}, // 8
- // LC3 Specification d09r01.pdf; Page 103 of 177
- {+1.447755801787238e+00, +2.723999516749523e+00, +2.310832687375278e+00,
- +9.350512695665294e-01, -2.747439113836877e-01, -9.020776968286019e-01,
- -9.406815119454044e-01, -6.336970389743102e-01}, // 9
- {+7.933545264174744e-01, +1.439311855234535e-02, -5.678348447296789e-01,
- -6.547604679167449e-01, -4.794589984757430e-01, -1.738946619028885e-01,
- +6.801627055154381e-02, +2.951259483697938e-01}, // 10
- {+2.724253473850336e+00, +2.959475724048243e+00, +1.849535592684608e+00,
- +5.632849223223643e-01, +1.399170881250724e-01, +3.596410933662221e-01,
- +6.894613547745887e-01, +6.397901768331046e-01}, // 11
- {-5.308301983754000e-01, -2.126906828121638e-01, +5.766136283770966e-03,
- +4.248714843837454e-01, +4.731289521586675e-01, +8.588941993212806e-01,
- +1.191111608544352e+00, +9.961896696383581e-01}, // 12
- {+1.687284108450062e+00, +2.436145092376558e+00, +2.330194290782250e+00,
- +1.779837778350905e+00, +1.444112953900818e+00, +1.519951770097301e+00,
- +1.471993937504249e+00, +9.776824738917613e-01}, // 13
- {-2.951832728018580e+00, -1.593934967733454e+00, -1.099187728780224e-01,
- +3.886090729192574e-01, +5.129326495175837e-01, +6.281125970634966e-01,
- +8.226217964306339e-01, +8.758914246550805e-01}, // 14
- {+1.018783427856281e-01, +5.898573242289165e-01, +6.190476467934656e-01,
- +1.267313138517963e+00, +2.419610477698038e+00, +2.251742525721865e+00,
- +5.265370309912005e-01, -3.965915132279989e-01}, // 15
- {+2.682545754984259e+00, +1.327380108994199e+00, +1.301852738040482e-01,
- -3.385330885113471e-01, -3.682192358996665e-01, -1.916899467159607e-01,
- -1.547823771539079e-01, -2.342071777743923e-01}, // 16
- {+4.826979236804030e+00, +3.119478044924880e+00, +1.395136713851784e+00,
- +2.502953159187215e-01, -3.936138393797931e-01, -6.434581730547007e-01,
- -6.425707368569433e-01, -7.231932234440720e-01}, // 17
- {+8.784199364703349e-02, -5.695868402385010e-01, -1.145060156688110e+00,
- -1.669684881725975e+00, -1.845344176036817e+00, -1.564680273288019e+00,
- -1.117467590764198e+00, -5.339816633667862e-01}, // 18
- {+1.391023082043259e+00, +1.981464791994655e+00, +1.112657963887701e+00,
- -2.201075094207434e-01, -7.749656115523655e-01, -5.940638741491173e-01,
- +1.369376806289231e-01, +8.182428912643381e-01}, // 19
- {+3.845858938891820e-01, -1.605887855365100e-01, -5.393668095577095e-01,
- -5.293090787898571e-01, +1.904335474379324e-01, +2.560629181065215e+00,
- +2.818963982452484e+00, +6.566708756961611e-01}, // 20
- {+1.932273994417191e+00, +3.010301804120569e+00, +3.065438938262036e+00,
- +2.501101608700079e+00, +1.930895929789344e+00, +5.721538109618367e-01,
- -8.117417940810907e-01, -1.176418108619025e+00}, // 21
- {+1.750804628998837e-01, -7.505228322489846e-01, -1.039438933422309e+00,
- -1.135775089376484e+00, -1.041979038374938e+00, -1.520600989933816e-02,
- +2.070483917167066e+00, +3.429489180816891e+00}, // 22
- // LC3 Specification d09r01.pdf; Page 104 of 177
- {-1.188170202505555e+00, +3.667928736626364e-01, +1.309578304090959e+00,
- +1.683306872804914e+00, +1.251009242251268e+00, +9.423757516286146e-01,
- +8.262504833741330e-01, +4.399527411209563e-01}, // 23
- {+2.533222033270612e+00, +2.112746426959081e+00, +1.262884115020644e+00,
- +7.615135124304274e-01, +5.221179379761699e-01, +1.186800697571213e-01,
- -4.523468275073703e-01, -7.003524261611032e-01}, // 24
- {+3.998898374856063e+00, +4.079017514519560e+00, +2.822856611024964e+00,
- +1.726072128495800e+00, +6.471443773486192e-01, -3.311485212172380e-01,
- -8.840425708487493e-01, -1.126973406454781e+00}, // 25
- {+5.079025931863813e-01, +1.588384497895265e+00, +1.728990238692094e+00,
- +1.006922302417256e+00, +3.771212318163816e-01, +4.763707668994976e-01,
- +1.087547403721699e+00, +1.087562660992209e+00}, // 26
- {+3.168568251075689e+00, +3.258534581594065e+00, +2.422305913285988e+00,
- +1.794460776432612e+00, +1.521779106530886e+00, +1.171967065376021e+00,
- +4.893945969806952e-01, -6.227957157187685e-02}, // 27
- {+1.894147667317636e+00, +1.251086946092320e+00, +5.904512107206275e-01,
- +6.083585832937136e-01, +8.781710100110816e-01, +1.119125109509496e+00,
- +1.018576615503421e+00, +6.204538910117241e-01}, // 28
- {+9.488806045171881e-01, +2.132394392499823e+00, +2.723453503442780e+00,
- +2.769860768665877e+00, +2.542869732549456e+00, +2.020462638250194e+00,
- +8.300458594009102e-01, -2.755691738882634e-02}, // 29
- {-1.880267570456275e+00, -1.264310727587049e+00, +3.114249769686986e-01,
- +1.836702103064300e+00, +2.256341918398738e+00, +2.048189984634735e+00,
- +2.195268374585677e+00, +2.026596138366193e+00}, // 30
- {+2.463757462771289e-01, +9.556217733930993e-01, +1.520467767417663e+00,
- +1.976474004194571e+00, +1.940438671774617e+00, +2.233758472826862e+00,
- +1.988359777584072e+00, +1.272326725547010e+00}}; // 31
-double HFCB[32][8] = {
- {+2.320284191244650e-01, -1.008902706044547e+00, -2.142235027894714e+00,
- -2.375338135706641e+00, -2.230419330496551e+00, -2.175958812236960e+00,
- -2.290659135409999e+00, -2.532863979798455e+00}, // 0
- {-1.295039366736175e+00, -1.799299653843385e+00, -1.887031475315188e+00,
- -1.809916596873323e+00, -1.763400384792061e+00, -1.834184284679500e+00,
- -1.804809806874051e+00, -1.736795453174010e+00}, // 1
- {+1.392857160458027e-01, -2.581851261717519e-01, -6.508045726701103e-01,
- -1.068157317819692e+00, -1.619287415243023e+00, -2.187625664417564e+00,
- -2.637575869390537e+00, -2.978977495750963e+00}, // 2
- {-3.165131021857248e-01, -4.777476572098050e-01, -5.511620758797545e-01,
- -4.847882833811970e-01, -2.383883944558142e-01, -1.430245072855038e-01,
- +6.831866736490735e-02, +8.830617172880660e-02}, // 3
- {+8.795184052264962e-01, +2.983400960071886e-01, -9.153863964057101e-01,
- // LC3 Specification d09r01.pdf; Page 105 of 177
- -2.206459747397620e+00, -2.741421809599509e+00, -2.861390742768913e+00,
- -2.888415971052714e+00, -2.951826082625207e+00}, // 4
- {-2.967019224553751e-01, -9.750049191745525e-01, -1.358575002469926e+00,
- -9.837211058374442e-01, -6.529569391008090e-01, -9.899869929218105e-01,
- -1.614672245988999e+00, -2.407123023851163e+00}, // 5
- {+3.409811004696971e-01, +2.688997889460545e-01, +5.633356848280326e-02,
- +4.991140468266853e-02, -9.541307274143691e-02, -7.601661460838854e-01,
- -2.327581201770068e+00, -3.771554853856562e+00}, // 6
- {-1.412297590775968e+00, -1.485221193498518e+00, -1.186035798347001e+00,
- -6.250016344413516e-01, +1.539024974683036e-01, +5.763864978107553e-01,
- +7.950926037988714e-01, +5.965646321449126e-01}, // 7
- {-2.288395118273794e-01, -3.337190697846616e-01, -8.093213593246560e-01,
- -1.635878769237973e+00, -1.884863973309819e+00, -1.644966913163562e+00,
- -1.405157780466116e+00, -1.466664713261457e+00}, // 8
- {-1.071486285444486e+00, -1.417670154562606e+00, -1.548917622654407e+00,
- -1.452960624755303e+00, -1.031829700622701e+00, -6.906426402725842e-01,
- -4.288438045321706e-01, -4.949602154088736e-01}, // 9
- {-5.909885111880511e-01, -7.117377585376282e-02, +3.457195229473127e-01,
- +3.005494609962507e-01, -1.118652182958568e+00, -2.440891511480490e+00,
- -2.228547324507349e+00, -1.895092282108533e+00}, // 10
- {-8.484340988361639e-01, -5.832268107088888e-01, +9.004236881428734e-02,
- +8.450250075568864e-01, +1.065723845017161e+00, +7.375829993777555e-01,
- +2.565904524599121e-01, -4.919633597623784e-01}, // 11
- {+1.140691455623824e+00, +9.640168923982929e-01, +3.814612059847975e-01,
- -4.828493406089983e-01, -1.816327212605887e+00, -2.802795127285548e+00,
- -3.233857248338638e+00, -3.459087144914729e+00}, // 12
- {-3.762832379674643e-01, +4.256754620961052e-02, +5.165476965923055e-01,
- +2.517168818646298e-01, -2.161799675243032e-01, -5.340740911245042e-01,
- -6.407860962621957e-01, -8.697450323741350e-01}, // 13
- {+6.650041205984020e-01, +1.097907646907945e+00, +1.383426671120792e+00,
- +1.343273586282854e+00, +8.229788368559223e-01, +2.158767985156789e-01,
- -4.049257530802925e-01, -1.070256058705229e+00}, // 14
- {-8.262659539826793e-01, -6.711812327666034e-01, -2.284955927794715e-01,
- +5.189808525519373e-01, +1.367218963402784e+00, +2.180230382530922e+00,
- +2.535960927501071e+00, +2.201210988600361e+00}, // 15
- {+1.410083268321729e+00, +7.544419078354684e-01, -1.305505849586310e+00,
- -1.871337113509707e+00, -1.240086851563054e+00, -1.267129248662737e+00,
- -2.036708130039070e+00, -2.896851622423807e+00}, // 16
- {+3.613868175743476e-01, -2.199917054278258e-02, -5.793688336338242e-01,
- -8.794279609410701e-01, -8.506850234081188e-01, -7.793970501558157e-01,
- -7.321829272918255e-01, -8.883485148212548e-01}, // 17
- {+4.374692393303287e-01, +3.054404196059607e-01, -7.387865664783739e-03,
- // LC3 Specification d09r01.pdf; Page 106 of 177
- -4.956498547102520e-01, -8.066512711183929e-01, -1.224318919844005e+00,
- -1.701577700431810e+00, -2.244919137556108e+00}, // 18
- {+6.481003189965029e-01, +6.822991336406795e-01, +2.532474643329756e-01,
- +7.358421437884688e-02, +3.142167093890103e-01, +2.347298809236790e-01,
- +1.446001344798368e-01, -6.821201788801744e-02}, // 19
- {+1.119198330913041e+00, +1.234655325360046e+00, +5.891702380853181e-01,
- -1.371924596531664e+00, -2.370957072415767e+00, -2.007797826823599e+00,
- -1.666885402243946e+00, -1.926318462584058e+00}, // 20
- {+1.418474970871759e-01, -1.106600706331509e-01, -2.828245925436287e-01,
- -6.598134746141936e-03, +2.859292796272158e-01, +4.604455299529710e-02,
- -6.025964155778858e-01, -2.265687286325748e+00}, // 21
- {+5.040469553902519e-01, +8.269821629590972e-01, +1.119812362918282e+00,
- +1.179140443327336e+00, +1.079874291972597e+00, +6.975362390675000e-01,
- -9.125488173710808e-01, -3.576847470627726e+00}, // 22
- {-5.010760504793567e-01, -3.256780060814170e-01, +2.807981949470768e-02,
- +2.620545547631326e-01, +3.605908060857668e-01, +6.356237220536995e-01,
- +9.590124671781544e-01, +1.307451566886533e+00}, // 23
- {+3.749709827096420e+00, +1.523426118470452e+00, -4.577156618978547e-01,
- -7.987110082431923e-01, -3.868193293091003e-01, -3.759010622312032e-01,
- -6.578368999305377e-01, -1.281639642436027e+00}, // 24
- {-1.152589909805491e+00, -1.108008859062412e+00, -5.626151165124718e-01,
- -2.205621237656746e-01, -3.498428803366437e-01, -7.534327702504950e-01,
- -9.885965933963837e-01, -1.287904717914711e+00}, // 25
- {+1.028272464221398e+00, +1.097705193898282e+00, +7.686455457647760e-01,
- +2.060819777407656e-01, -3.428057350919982e-01, -7.549394046253397e-01,
- -1.041961776319998e+00, -1.503356529555287e+00}, // 26
- {+1.288319717078174e-01, +6.894393952648783e-01, +1.123469050095749e+00,
- +1.309345231065936e+00, +1.355119647139345e+00, +1.423113814707990e+00,
- +1.157064491909045e+00, +4.063194375168383e-01}, // 27
- {+1.340330303347565e+00, +1.389968250677893e+00, +1.044679217088833e+00,
- +6.358227462443666e-01, -2.747337555184823e-01, -1.549233724306950e+00,
- -2.442397102780069e+00, -3.024576069445502e+00}, // 28
- {+2.138431054193125e+00, +4.247112673031041e+00, +2.897341098304393e+00,
- +9.327306580268148e-01, -2.928222497298096e-01, -8.104042968531823e-01,
- -7.888680987564828e-01, -9.353531487613377e-01}, // 29
- {+5.648304873553961e-01, +1.591849779587432e+00, +2.397716990151462e+00,
- +3.036973436007040e+00, +2.664243503371508e+00, +1.393044850326060e+00,
- +4.038340235957454e-01, -6.562709713281135e-01}, // 30
- {-4.224605475860865e-01, +3.261496250498011e-01, +1.391713133422612e+00,
- +2.231466146364735e+00, +2.611794421696881e+00, +2.665403401965702e+00,
- +2.401035541057067e+00, +1.759203796708810e+00} // 31
-};
-// LC3 Specification d09r01.pdf; Page 107 of 177
-double sns_vq_reg_adj_gains[2] = {8915.0 / 4096.0, 12054.0 / 4096.0};
-double sns_vq_reg_lf_adj_gains[4] = {6245.0 / 4096.0, 15043.0 / 4096.0,
- 17861.0 / 4096.0, 21014.0 / 4096.0};
-double sns_vq_near_adj_gains[4] = {7099.0 / 4096.0, 9132.0 / 4096.0,
- 11253.0 / 4096.0, 14808.0 / 4096.0};
-double sns_vq_far_adj_gains[8] = {
- 4336.0 / 4096.0, 5067.0 / 4096.0, 5895.0 / 4096.0, 8149.0 / 4096.0,
- 10235.0 / 4096.0, 12825.0 / 4096.0, 16868.0 / 4096.0, 19882.0 / 4096.0};
-int sns_gainMSBbits[4] = {1, 1, 2, 2};
-int sns_gainLSBbits[4] = {0, 1, 0, 1};
-unsigned int MPVQ_offsets[16][1 + 10] = {
- /* k=0, k=1, k=2,... , k=10 */
- {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* n=0*/
- {0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19}, /* n=1*/
- {0, 1, 5, 13, 25, 41, 61, 85, 113, 145, 181},
- {0, 1, 7, 25, 63, 129, 231, 377, 575, 833, 1159},
- {0, 1, 9, 41, 129, 321, 681, 1289, 2241, 3649, 5641},
- {0, 1, 11, 61, 231, 681, 1683, 3653, 7183, 13073, 22363},
- {0, 1, 13, 85, 377, 1289, 3653, 8989, 19825, 40081, 75517},
- {0, 1, 15, 113, 575, 2241, 7183, 19825, 48639, 108545, 224143},
- {0, 1, 17, 145, 833, 3649, 13073, 40081, 108545, 265729, 598417},
- {0, 1, 19, 181, 1159, 5641, 22363, 75517, 224143, 598417, 1462563},
- {0, 1, 21, 221, 1561, 8361, 36365, 134245, 433905, 1256465, 3317445},
- {0, 1, 23, 265, 2047, 11969, 56695, 227305, 795455, 2485825, 7059735},
- {0, 1, 25, 313, 2625, 16641, 85305, 369305, 1392065, 4673345, 14218905},
- {0, 1, 27, 365, 3303, 22569, 124515, 579125, 2340495, 8405905, 27298155},
- {0, 1, 29, 421, 4089, 29961, 177045, 880685, 3800305, 14546705,
- 50250765}, /* n=14*/
- {0, 1, 31, 481, 4991, 39041, 246047, 1303777, 5984767, 24331777,
- 89129247}, /* n=15*/
-};
-double D[16][16] = {
- /* D consists of the base vectors of the DCT (orthogonalized DCT-II)*/
- /* (the DCT base vector are stored in column-wise in this table)*/
- /* first row results in the first coeff in fwd synthesis (dec+(enc))*/
- /* first column results in the first coeff in the analysis(encoder) */
- {+2.500000000000000e-01, +3.518509343815957e-01, +3.467599613305369e-01,
- +3.383295002935882e-01, +3.266407412190941e-01, +3.118062532466678e-01,
- +2.939689006048397e-01, +2.733004667504394e-01, +2.500000000000001e-01,
- +2.242918965856591e-01, +1.964237395967756e-01, +1.666639146194367e-01,
- +1.352990250365493e-01, +1.026311318805893e-01, +6.897484482073578e-02,
- +3.465429229977293e-02}, // 0 Note: needed a ',' as correction compared to
- // d09r01 (already fixed in d09r02_F2F)
- {+2.500000000000000e-01, +3.383295002935882e-01, +2.939689006048397e-01,
- +2.242918965856591e-01, +1.352990250365493e-01, +3.465429229977286e-02,
- -6.897484482073579e-02, -1.666639146194366e-01, -2.500000000000001e-01,
- -3.118062532466678e-01, -3.467599613305369e-01, -3.518509343815956e-01,
- -3.266407412190941e-01, -2.733004667504394e-01, -1.964237395967756e-01,
- -1.026311318805893e-01}, // 1
- // LC3 Specification d09r01.pdf; Page 108 of 177
- {+2.500000000000000e-01, +3.118062532466678e-01, +1.964237395967756e-01,
- +3.465429229977286e-02, -1.352990250365493e-01, -2.733004667504394e-01,
- -3.467599613305369e-01, -3.383295002935882e-01, -2.500000000000001e-01,
- -1.026311318805894e-01, +6.897484482073574e-02, +2.242918965856590e-01,
- +3.266407412190941e-01, +3.518509343815957e-01, +2.939689006048397e-01,
- +1.666639146194367e-01}, // 2
- {+2.500000000000000e-01, +2.733004667504394e-01, +6.897484482073575e-02,
- -1.666639146194366e-01, -3.266407412190941e-01, -3.383295002935882e-01,
- -1.964237395967755e-01, +3.465429229977288e-02, +2.500000000000001e-01,
- +3.518509343815957e-01, +2.939689006048397e-01, +1.026311318805893e-01,
- -1.352990250365493e-01, -3.118062532466679e-01, -3.467599613305369e-01,
- -2.242918965856590e-01}, // 3
- {+2.500000000000000e-01, +2.242918965856591e-01, -6.897484482073575e-02,
- -3.118062532466678e-01, -3.266407412190941e-01, -1.026311318805894e-01,
- +1.964237395967755e-01, +3.518509343815957e-01, +2.500000000000001e-01,
- -3.465429229977282e-02, -2.939689006048397e-01, -3.383295002935882e-01,
- -1.352990250365493e-01, +1.666639146194367e-01, +3.467599613305369e-01,
- +2.733004667504394e-01}, // 4
- {+2.500000000000000e-01, +1.666639146194366e-01, -1.964237395967756e-01,
- -3.518509343815956e-01, -1.352990250365493e-01, +2.242918965856591e-01,
- +3.467599613305369e-01, +1.026311318805894e-01, -2.500000000000001e-01,
- -3.383295002935882e-01, -6.897484482073574e-02, +2.733004667504394e-01,
- +3.266407412190941e-01, +3.465429229977289e-02, -2.939689006048397e-01,
- -3.118062532466677e-01}, // 5
- {+2.500000000000000e-01, +1.026311318805894e-01, -2.939689006048397e-01,
- -2.733004667504393e-01, +1.352990250365493e-01, +3.518509343815957e-01,
- +6.897484482073579e-02, -3.118062532466678e-01, -2.500000000000001e-01,
- +1.666639146194366e-01, +3.467599613305369e-01, +3.465429229977293e-02,
- -3.266407412190941e-01, -2.242918965856591e-01, +1.964237395967756e-01,
- +3.383295002935882e-01}, // 6
- {+2.500000000000000e-01, +3.465429229977287e-02, -3.467599613305369e-01,
- -1.026311318805893e-01, +3.266407412190941e-01, +1.666639146194366e-01,
- -2.939689006048397e-01, -2.242918965856591e-01, +2.500000000000001e-01,
- +2.733004667504393e-01, -1.964237395967756e-01, -3.118062532466678e-01,
- +1.352990250365493e-01, +3.383295002935882e-01, -6.897484482073578e-02,
- -3.518509343815956e-01}, // 7
- {+2.500000000000000e-01, -3.465429229977287e-02, -3.467599613305369e-01,
- +1.026311318805893e-01, +3.266407412190941e-01, -1.666639146194366e-01,
- -2.939689006048397e-01, +2.242918965856591e-01, +2.500000000000001e-01,
- -2.733004667504393e-01, -1.964237395967756e-01, +3.118062532466678e-01,
- +1.352990250365493e-01, -3.383295002935882e-01, -6.897484482073578e-02,
- +3.518509343815956e-01}, // 8
- {+2.500000000000000e-01, -1.026311318805894e-01, -2.939689006048397e-01,
- +2.733004667504393e-01, +1.352990250365493e-01, -3.518509343815957e-01,
- +6.897484482073579e-02, +3.118062532466678e-01, -2.500000000000001e-01,
- -1.666639146194366e-01, +3.467599613305369e-01, -3.465429229977293e-02,
- -3.266407412190941e-01, +2.242918965856591e-01, +1.964237395967756e-01,
- -3.383295002935882e-01}, // 9
- // LC3 Specification d09r01.pdf; Page 109 of 177
- {+2.500000000000000e-01, -1.666639146194366e-01, -1.964237395967756e-01,
- +3.518509343815956e-01, -1.352990250365493e-01, -2.242918965856591e-01,
- +3.467599613305369e-01, -1.026311318805894e-01, -2.500000000000001e-01,
- +3.383295002935882e-01, -6.897484482073574e-02, -2.733004667504394e-01,
- +3.266407412190941e-01, -3.465429229977289e-02, -2.939689006048397e-01,
- +3.118062532466677e-01}, // 10
- {+2.500000000000000e-01, -2.242918965856591e-01, -6.897484482073575e-02,
- +3.118062532466678e-01, -3.266407412190941e-01, +1.026311318805894e-01,
- +1.964237395967755e-01, -3.518509343815957e-01, +2.500000000000001e-01,
- +3.465429229977282e-02, -2.939689006048397e-01, +3.383295002935882e-01,
- -1.352990250365493e-01, -1.666639146194367e-01, +3.467599613305369e-01,
- -2.733004667504394e-01}, // 11
- {+2.500000000000000e-01, -2.733004667504394e-01, +6.897484482073575e-02,
- +1.666639146194366e-01, -3.266407412190941e-01, +3.383295002935882e-01,
- -1.964237395967755e-01, -3.465429229977288e-02, +2.500000000000001e-01,
- -3.518509343815957e-01, +2.939689006048397e-01, -1.026311318805893e-01,
- -1.352990250365493e-01, +3.118062532466679e-01, -3.467599613305369e-01,
- +2.242918965856590e-01}, // 12
- {+2.500000000000000e-01, -3.118062532466678e-01, +1.964237395967756e-01,
- -3.465429229977286e-02, -1.352990250365493e-01, +2.733004667504394e-01,
- -3.467599613305369e-01, +3.383295002935882e-01, -2.500000000000001e-01,
- +1.026311318805894e-01, +6.897484482073574e-02, -2.242918965856590e-01,
- +3.266407412190941e-01, -3.518509343815957e-01, +2.939689006048397e-01,
- -1.666639146194367e-01}, // 13
- {+2.500000000000000e-01, -3.383295002935882e-01, +2.939689006048397e-01,
- -2.242918965856591e-01, +1.352990250365493e-01, -3.465429229977286e-02,
- -6.897484482073579e-02, +1.666639146194366e-01, -2.500000000000001e-01,
- +3.118062532466678e-01, -3.467599613305369e-01, +3.518509343815956e-01,
- -3.266407412190941e-01, +2.733004667504394e-01, -1.964237395967756e-01,
- +1.026311318805893e-01}, // 14
- {+2.500000000000000e-01, -3.518509343815957e-01, +3.467599613305369e-01,
- -3.383295002935882e-01, +3.266407412190941e-01, -3.118062532466678e-01,
- +2.939689006048397e-01, -2.733004667504394e-01, +2.500000000000001e-01,
- -2.242918965856591e-01, +1.964237395967756e-01, -1.666639146194367e-01,
- +1.352990250365493e-01, -1.026311318805893e-01, +6.897484482073578e-02,
- -3.465429229977293e-02}}; // 15
diff --git a/system/embdrv/lc3_dec/Common/Tables/SnsQuantizationTables.hpp b/system/embdrv/lc3_dec/Common/Tables/SnsQuantizationTables.hpp
deleted file mode 100644
index 2d447398ca..0000000000
--- a/system/embdrv/lc3_dec/Common/Tables/SnsQuantizationTables.hpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * SnsQuantizationTables.hpp
- *
- * 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.
- */
-
-#ifndef SNS_QUANTIZATION_TABLES_H_
-#define SNS_QUANTIZATION_TABLES_H_
-
-// LC3 Specification d09r01.pdf
-// Section 5.7.3 SNS Quantization
-
-// LC3 Specification d09r04_*implementorComments*
-// Section 3.7.4 SNS Quantization
-
-extern double LFCB[32][8];
-extern double HFCB[32][8];
-extern double sns_vq_reg_adj_gains[2];
-extern double sns_vq_reg_lf_adj_gains[4];
-extern double sns_vq_near_adj_gains[4];
-extern double sns_vq_far_adj_gains[8];
-extern int sns_gainMSBbits[4];
-extern int sns_gainLSBbits[4];
-extern unsigned int MPVQ_offsets[16][1 + 10];
-extern double D[16][16];
-
-#endif // SNS_QUANTIZATION_TABLES_H_
diff --git a/system/embdrv/lc3_dec/Common/Tables/SpectralDataTables.cpp b/system/embdrv/lc3_dec/Common/Tables/SpectralDataTables.cpp
deleted file mode 100644
index 2ed6b15257..0000000000
--- a/system/embdrv/lc3_dec/Common/Tables/SpectralDataTables.cpp
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
- * SpectralDataTables.cpp
- *
- * 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.
- */
-
-// LC3 Specification d09r01.pdf
-// Section 5.7.6 Spectral data
-#include "SpectralDataTables.hpp"
-
-// LC3 Specification d09r01.pdf; Page 114 of 177
-unsigned char ac_spec_lookup[4096] = {
- 0x01, 0x27, 0x07, 0x19, 0x16, 0x16, 0x1C, 0x16, 0x16, 0x16, 0x16, 0x1C,
- 0x1C, 0x1C, 0x22, 0x1F, 0x1F, 0x28, 0x2B, 0x2E, 0x31, 0x34, 0x0E, 0x11,
- 0x24, 0x24, 0x24, 0x26, 0x00, 0x39, 0x26, 0x16, 0x00, 0x08, 0x09, 0x0B,
- 0x2F, 0x0E, 0x0E, 0x11,
- // LC3 Specification d09r01.pdf; Page 115 of 177
- 0x24, 0x24, 0x24, 0x26, 0x3B, 0x3B, 0x26, 0x16, 0x16, 0x1A, 0x2E, 0x1D,
- 0x1E, 0x20, 0x21, 0x23, 0x24, 0x24, 0x24, 0x26, 0x00, 0x3B, 0x17, 0x16,
- 0x2E, 0x2E, 0x2D, 0x2F, 0x30, 0x32, 0x32, 0x12, 0x36, 0x36, 0x36, 0x26,
- 0x3B, 0x3B, 0x3B, 0x16, 0x00, 0x3E, 0x3F, 0x03, 0x21, 0x02, 0x02, 0x3D,
- 0x14, 0x14, 0x14, 0x15, 0x3B, 0x3B, 0x27, 0x1C, 0x1C, 0x3F, 0x3F, 0x03,
- 0x21, 0x02, 0x02, 0x3D, 0x26, 0x26, 0x26, 0x15, 0x3B, 0x3B, 0x27, 0x1C,
- 0x1C, 0x06, 0x06, 0x06, 0x02, 0x12, 0x3D, 0x14, 0x15, 0x15, 0x15, 0x3B,
- 0x27, 0x27, 0x07, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x33, 0x33, 0x33,
- 0x35, 0x36, 0x14, 0x26, 0x26, 0x39, 0x27, 0x27, 0x27, 0x07, 0x18, 0x22,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x38, 0x26, 0x39,
- 0x39, 0x3B, 0x07, 0x07, 0x07, 0x2A, 0x2A, 0x22, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x05, 0x04, 0x04, 0x05, 0x15, 0x15, 0x3B, 0x07, 0x07, 0x07, 0x07,
- 0x19, 0x19, 0x19, 0x22, 0x04, 0x04, 0x04, 0x04, 0x05, 0x17, 0x17, 0x27,
- 0x07, 0x07, 0x07, 0x2A, 0x19, 0x19, 0x16, 0x1F, 0x1F, 0x27, 0x27, 0x27,
- 0x27, 0x07, 0x07, 0x2A, 0x00, 0x19, 0x16, 0x16, 0x16, 0x1C, 0x22, 0x1F,
- 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
- 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x28, 0x08, 0x09, 0x31, 0x31, 0x34,
- 0x11, 0x11, 0x11, 0x04, 0x00, 0x14, 0x11, 0x3C, 0x28, 0x28, 0x08, 0x2B,
- 0x1B, 0x31, 0x31, 0x0E, 0x11, 0x11, 0x11, 0x24, 0x2A, 0x2A, 0x11, 0x39,
- 0x39, 0x28, 0x08, 0x1A, 0x1B, 0x31, 0x0C, 0x0E, 0x11, 0x11, 0x11, 0x24,
- 0x00, 0x26, 0x24, 0x01, 0x08, 0x08, 0x2B, 0x09, 0x0B, 0x31, 0x0C, 0x0E,
- 0x0E, 0x21, 0x32, 0x32, 0x32, 0x3D, 0x24, 0x27, 0x08, 0x08, 0x2B, 0x2E,
- 0x31, 0x34, 0x1E, 0x0E, 0x0E, 0x21, 0x32, 0x32, 0x32, 0x32, 0x12, 0x19,
- 0x08, 0x08, 0x2B, 0x2E, 0x31, 0x34, 0x1E, 0x0E, 0x0E, 0x12, 0x05, 0x05,
- 0x05, 0x3D, 0x12, 0x17, 0x2B, 0x2B, 0x2B, 0x09, 0x31, 0x34, 0x03, 0x0E,
- 0x0E, 0x32, 0x32, 0x32, 0x32, 0x3D, 0x11, 0x18, 0x2B, 0x2B, 0x2B, 0x2B,
- 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B,
- 0x2B, 0x2B, 0x2B, 0x09, 0x0B, 0x34, 0x34, 0x0E, 0x0E, 0x11, 0x3D, 0x3D,
- 0x3D, 0x36, 0x11, 0x27, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
- 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2C, 0x1B,
- 0x1D, 0x34, 0x30, 0x34, 0x34, 0x11, 0x11, 0x11, 0x11, 0x02, 0x11, 0x07,
- 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B,
- 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x09, 0x1B, 0x1B, 0x0C, 0x34, 0x0E,
- 0x0E, 0x3A, 0x29, 0x29, 0x29, 0x06, 0x11, 0x25, 0x09, 0x09, 0x09, 0x1B,
- 0x0B, 0x31, 0x0C, 0x34,
- // LC3 Specification d09r01.pdf; Page 116 of 177
- 0x0E, 0x0E, 0x0E, 0x32, 0x00, 0x35, 0x11, 0x1C, 0x34, 0x34, 0x31, 0x34,
- 0x0C, 0x34, 0x1E, 0x0E, 0x0E, 0x11, 0x02, 0x02, 0x02, 0x26, 0x26, 0x22,
- 0x1F, 0x22, 0x22, 0x1F, 0x1F, 0x1F, 0x1F, 0x13, 0x13, 0x13, 0x13, 0x13,
- 0x13, 0x13, 0x1F, 0x13, 0x2C, 0x2C, 0x3E, 0x1E, 0x20, 0x3A, 0x23, 0x24,
- 0x24, 0x26, 0x00, 0x3B, 0x07, 0x07, 0x27, 0x22, 0x22, 0x2D, 0x2F, 0x30,
- 0x21, 0x23, 0x23, 0x24, 0x26, 0x26, 0x26, 0x3B, 0x07, 0x07, 0x27, 0x22,
- 0x22, 0x3E, 0x1E, 0x0F, 0x32, 0x35, 0x35, 0x36, 0x15, 0x15, 0x15, 0x3B,
- 0x07, 0x07, 0x07, 0x22, 0x1E, 0x1E, 0x30, 0x21, 0x3A, 0x12, 0x12, 0x38,
- 0x17, 0x17, 0x17, 0x3B, 0x07, 0x07, 0x18, 0x22, 0x22, 0x06, 0x06, 0x3A,
- 0x35, 0x36, 0x36, 0x15, 0x3B, 0x3B, 0x3B, 0x27, 0x07, 0x07, 0x2A, 0x22,
- 0x06, 0x06, 0x21, 0x3A, 0x35, 0x36, 0x3D, 0x15, 0x3B, 0x3B, 0x3B, 0x27,
- 0x07, 0x07, 0x2A, 0x22, 0x22, 0x33, 0x33, 0x35, 0x36, 0x38, 0x38, 0x39,
- 0x27, 0x27, 0x27, 0x07, 0x2A, 0x2A, 0x19, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
- 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
- 0x1F, 0x04, 0x04, 0x04, 0x05, 0x17, 0x17, 0x27, 0x07, 0x07, 0x07, 0x2A,
- 0x19, 0x19, 0x16, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
- 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x05, 0x05, 0x05,
- 0x05, 0x39, 0x39, 0x27, 0x18, 0x18, 0x18, 0x2A, 0x16, 0x16, 0x1C, 0x1F,
- 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
- 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x29, 0x29, 0x29, 0x29, 0x27, 0x27, 0x07,
- 0x2A, 0x2A, 0x2A, 0x19, 0x1C, 0x1C, 0x1C, 0x1F, 0x1F, 0x29, 0x29, 0x29,
- 0x29, 0x27, 0x27, 0x18, 0x19, 0x19, 0x19, 0x16, 0x1C, 0x1C, 0x22, 0x1F,
- 0x1F, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x1C, 0x22, 0x22, 0x22, 0x22,
- 0x22, 0x22, 0x1F, 0x13, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x0B,
- 0x2F, 0x20, 0x32, 0x12, 0x12, 0x14, 0x15, 0x15, 0x15, 0x27, 0x3B, 0x22,
- 0x1A, 0x1A, 0x1B, 0x1D, 0x1E, 0x21, 0x32, 0x12, 0x12, 0x14, 0x39, 0x39,
- 0x39, 0x3B, 0x3B, 0x22, 0x1B, 0x1B, 0x0B, 0x0C, 0x30, 0x32, 0x3A, 0x3D,
- 0x3D, 0x38, 0x39, 0x39, 0x39, 0x3B, 0x27, 0x22, 0x2D, 0x2D, 0x0C, 0x1E,
- 0x20, 0x02, 0x02, 0x3D, 0x26, 0x26, 0x26, 0x39, 0x00, 0x3B, 0x27, 0x22,
- 0x3F, 0x3F, 0x03, 0x20, 0x3A, 0x12, 0x12, 0x14, 0x15, 0x15, 0x15, 0x3B,
- 0x27, 0x27, 0x07, 0x1F, 0x1F, 0x03, 0x03, 0x21, 0x3A, 0x12, 0x12, 0x14,
- 0x15, 0x15, 0x15, 0x3B, 0x07, 0x07, 0x07, 0x1F, 0x06, 0x06, 0x33, 0x33,
- 0x35, 0x36, 0x36, 0x26, 0x39, 0x39, 0x39, 0x27, 0x07, 0x07, 0x2A, 0x1F,
- 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
- 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x33, 0x35, 0x35, 0x36, 0x38, 0x38, 0x39,
- 0x3B, 0x3B, 0x3B, 0x07, 0x18, 0x18, 0x19, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
- 0x1F, 0x1F, 0x1F, 0x1F,
- // LC3 Specification d09r01.pdf; Page 117 of 177
- 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x04, 0x04, 0x04,
- 0x36, 0x15, 0x15, 0x39, 0x27, 0x27, 0x27, 0x07, 0x2A, 0x2A, 0x16, 0x1F,
- 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
- 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x05, 0x05, 0x05, 0x05, 0x17, 0x17, 0x3B,
- 0x07, 0x07, 0x07, 0x2A, 0x16, 0x16, 0x1C, 0x1F, 0x1F, 0x04, 0x04, 0x04,
- 0x05, 0x17, 0x17, 0x27, 0x18, 0x18, 0x18, 0x19, 0x1C, 0x1C, 0x22, 0x1F,
- 0x1F, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x1C, 0x22, 0x22, 0x22, 0x1F,
- 0x1F, 0x1F, 0x1F, 0x13, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x10, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x3C,
- 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C,
- 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C,
- 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C,
- 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C,
- 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C,
- 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C,
- 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D,
- 0x0D, 0x0D, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C,
- 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- // LC3 Specification d09r01.pdf; Page 118 of 177
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x00, 0x0D, 0x3C,
- 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C,
- 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00,
- 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x25,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x10,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x10, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x3C, 0x3C, 0x10, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x10, 0x3C, 0x3C, 0x3C, 0x3C,
- 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x25,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- // LC3 Specification d09r01.pdf; Page 119 of 177
- 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x3C, 0x3C, 0x3C, 0x10, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x25,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- // LC3 Specification d09r01.pdf; Page 120 of 177
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D,
- 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x0D, 0x0D, 0x0D, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x0D, 0x0D,
- 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00,
- 0x00, 0x00, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x0D, 0x0D, 0x0D, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x3C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C,
- 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D,
- 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D,
- 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- // LC3 Specification d09r01.pdf; Page 121 of 177
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x3C, 0x3C, 0x3C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x0D, 0x0D, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x3C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x3C,
- 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- // LC3 Specification d09r01.pdf; Page 122 of 177
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- // LC3 Specification d09r01.pdf; Page 123 of 177
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- // LC3 Specification d09r01.pdf; Page 124 of 177
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-short ac_spec_cumfreq[64][17] = {
- {0, 1, 2, 177, 225, 226, 227, 336, 372, 543, 652, 699, 719, 768, 804, 824,
- 834},
- {0, 18, 44, 61, 71, 98, 135, 159, 175, 197, 229, 251, 265, 282, 308, 328,
- 341},
- {0, 71, 163, 212, 237, 318, 420, 481, 514, 556, 613, 652, 675, 697, 727,
- 749, 764},
- {0, 160, 290, 336, 354, 475, 598, 653, 677, 722, 777, 808, 823, 842, 866,
- 881, 890},
- {0, 71, 144, 177, 195, 266, 342, 385, 411, 445, 489, 519, 539, 559, 586,
- 607, 622},
- {0, 48, 108, 140, 159, 217, 285, 327, 354, 385, 427, 457, 478, 497, 524,
- 545, 561},
- {0, 138, 247, 290, 308, 419, 531, 584, 609, 655, 710, 742, 759, 780, 807,
- 825, 836},
- {0, 16, 40, 62, 79, 103, 139, 170, 195, 215, 245, 270, 290, 305, 327, 346,
- 362},
- {0, 579, 729, 741, 743, 897, 970, 980, 982, 996, 1007, 1010, 1011, 1014,
- 1017, 1018, 1019},
- {0, 398, 582, 607, 612, 788, 902, 925, 931, 956, 979, 987, 990, 996, 1002,
- 1005, 1007},
- {0, 13, 34, 52, 63, 83, 112, 134, 149, 163, 183, 199, 211, 221, 235, 247,
- 257},
- {0, 281, 464, 501, 510, 681, 820, 857, 867, 902, 938, 953, 959, 968, 978,
- 984, 987},
- {0, 198, 362, 408, 421, 575, 722, 773, 789, 832, 881, 905, 915, 928, 944,
- 954, 959},
- {0, 1, 2, 95, 139, 140, 141, 213, 251, 337, 407, 450, 475, 515, 551, 576,
- 592},
- {0, 133, 274, 338, 366, 483, 605, 664, 691, 730, 778, 807, 822, 837, 857,
- 870, 878},
- {0, 128, 253, 302, 320, 443, 577, 636, 659, 708, 767, 799, 814, 833, 857,
- 872, 881},
- {0, 1, 2, 25, 42, 43, 44, 67, 85, 105, 126, 144, 159, 174, 191, 205, 217},
- {0, 70, 166, 229, 267, 356, 468, 533, 569, 606, 653, 685, 705, 722, 745,
- 762, 774},
- {0, 55, 130, 175, 200, 268, 358, 416, 449, 488, 542, 581, 606, 628, 659,
- 683, 699},
- {0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31},
- {0, 34, 85, 123, 147, 196, 265, 317, 352, 386, 433, 470, 497, 518, 549, 574,
- 593},
- {0, 30, 73, 105, 127, 170, 229, 274, 305, 335, 377, 411, 436, 455, 483, 506,
- 524},
- {0, 9, 24, 38, 51, 65, 87, 108, 126, 139, 159, 177, 193, 204, 221, 236,
- 250},
- {0, 30, 74, 105, 125, 166, 224, 266, 294, 322, 361, 391, 413, 431, 457, 478,
- 494},
- {0, 15, 38, 58, 73, 95, 128, 156, 178, 196, 222, 245, 263, 276, 296, 314,
- 329},
- // LC3 Specification d09r01.pdf; Page 125 of 177
- {0, 11, 28, 44, 57, 74, 100, 123, 142, 157, 179, 199, 216, 228, 246, 262,
- 276},
- {0, 448, 619, 639, 643, 821, 926, 944, 948, 971, 991, 998, 1000, 1005, 1010,
- 1012, 1013},
- {0, 332, 520, 549, 555, 741, 874, 903, 910, 940, 970, 981, 985, 991, 998,
- 1002, 1004},
- {0, 8, 21, 34, 45, 58, 78, 96, 112, 124, 141, 157, 170, 180, 194, 207, 219},
- {0, 239, 415, 457, 468, 631, 776, 820, 833, 872, 914, 933, 940, 951, 964,
- 971, 975},
- {0, 165, 310, 359, 375, 513, 652, 707, 727, 774, 828, 856, 868, 884, 904,
- 916, 923},
- {0, 3, 8, 13, 18, 23, 30, 37, 44, 48, 55, 62, 68, 72, 78, 84, 90},
- {0, 115, 237, 289, 311, 422, 547, 608, 635, 680, 737, 771, 788, 807, 832,
- 849, 859},
- {0, 107, 221, 272, 293, 399, 521, 582, 610, 656, 714, 749, 767, 787, 813,
- 831, 842},
- {0, 6, 16, 26, 35, 45, 60, 75, 89, 98, 112, 125, 137, 145, 157, 168, 178},
- {0, 72, 160, 210, 236, 320, 422, 482, 514, 555, 608, 644, 665, 685, 712,
- 732, 745},
- {0, 45, 108, 153, 183, 244, 327, 385, 421, 455, 502, 536, 559, 578, 605,
- 626, 641},
- {0, 1, 2, 9, 16, 17, 18, 26, 34, 40, 48, 55, 62, 68, 75, 82, 88},
- {0, 29, 73, 108, 132, 174, 236, 284, 318, 348, 391, 426, 452, 471, 500, 524,
- 543},
- {0, 20, 51, 76, 93, 123, 166, 200, 225, 247, 279, 305, 326, 342, 365, 385,
- 401},
- {0, 742, 845, 850, 851, 959, 997, 1001, 1002, 1009, 1014, 1016, 1017, 1019,
- 1020, 1021, 1022},
- {0, 42, 94, 121, 137, 186, 244, 280, 303, 330, 366, 392, 410, 427, 451, 470,
- 484},
- {0, 13, 33, 51, 66, 85, 114, 140, 161, 178, 203, 225, 243, 256, 275, 292,
- 307},
- {0, 501, 670, 689, 693, 848, 936, 952, 956, 975, 991, 997, 999, 1004, 1008,
- 1010, 1011},
- {0, 445, 581, 603, 609, 767, 865, 888, 895, 926, 954, 964, 968, 977, 986,
- 991, 993},
- {0, 285, 442, 479, 489, 650, 779, 818, 830, 870, 912, 930, 937, 949, 963,
- 971, 975},
- {0, 349, 528, 561, 569, 731, 852, 883, 892, 923, 953, 965, 970, 978, 987,
- 992, 994},
- {0, 199, 355, 402, 417, 563, 700, 750, 767, 811, 860, 884, 894, 909, 926,
- 936, 942},
- {0, 141, 275, 325, 343, 471, 606, 664, 686, 734, 791, 822, 836, 854, 877,
- 891, 899},
- {0, 243, 437, 493, 510, 649, 775, 820, 836, 869, 905, 923, 931, 941, 953,
- 960, 964},
- {0, 91, 197, 248, 271, 370, 487, 550, 580, 625, 684, 721, 741, 761, 788,
- 807, 819},
- {0, 107, 201, 242, 262, 354, 451, 503, 531, 573, 626, 660, 680, 701, 730,
- 751, 765},
- {0, 168, 339, 407, 432, 553, 676, 731, 755, 789, 830, 854, 866, 879, 895,
- 906, 912},
- // LC3 Specification d09r01.pdf; Page 126 of 177
- {0, 67, 147, 191, 214, 290, 384, 441, 472, 513, 567, 604, 627, 648, 678,
- 700, 715},
- {0, 46, 109, 148, 171, 229, 307, 359, 391, 427, 476, 513, 537, 558, 588,
- 612, 629},
- {0, 848, 918, 920, 921, 996, 1012, 1013, 1014, 1016, 1017, 1018, 1019, 1020,
- 1021, 1022, 1023},
- {0, 36, 88, 123, 145, 193, 260, 308, 340, 372, 417, 452, 476, 496, 525, 548,
- 565},
- {0, 24, 61, 90, 110, 145, 196, 237, 266, 292, 330, 361, 385, 403, 430, 453,
- 471},
- {0, 85, 182, 230, 253, 344, 454, 515, 545, 590, 648, 685, 706, 727, 756,
- 776, 789},
- {0, 22, 55, 82, 102, 135, 183, 222, 252, 278, 315, 345, 368, 385, 410, 431,
- 448},
- {0, 1, 2, 56, 89, 90, 91, 140, 172, 221, 268, 303, 328, 358, 388, 412, 430},
- {0, 45, 109, 152, 177, 239, 320, 376, 411, 448, 499, 537, 563, 585, 616,
- 640, 658},
- {0, 247, 395, 433, 445, 599, 729, 771, 785, 829, 875, 896, 905, 920, 937,
- 946, 951},
- {0, 231, 367, 408, 423, 557, 676, 723, 742, 786, 835, 860, 872, 889, 909,
- 921, 928}};
-short ac_spec_freq[64][17] = {
- {1, 1, 175, 48, 1, 1, 109, 36, 171, 109, 47, 20, 49, 36, 20, 10, 190},
- {18, 26, 17, 10, 27, 37, 24, 16, 22, 32, 22, 14, 17, 26, 20, 13, 683},
- {71, 92, 49, 25, 81, 102, 61, 33, 42, 57, 39, 23, 22, 30, 22, 15, 260},
- {160, 130, 46, 18, 121, 123, 55, 24, 45, 55, 31, 15, 19, 24, 15, 9, 134},
- {71, 73, 33, 18, 71, 76, 43, 26, 34, 44, 30, 20, 20, 27, 21, 15, 402},
- {48, 60, 32, 19, 58, 68, 42, 27, 31, 42, 30, 21, 19, 27, 21, 16, 463},
- {138, 109, 43, 18, 111, 112, 53, 25, 46, 55, 32, 17, 21, 27, 18, 11, 188},
- {16, 24, 22, 17, 24, 36, 31, 25, 20, 30, 25, 20, 15, 22, 19, 16, 662},
- {579, 150, 12, 2, 154, 73, 10, 2, 14, 11, 3, 1, 3, 3, 1, 1, 5},
- {398, 184, 25, 5, 176, 114, 23, 6, 25, 23, 8, 3, 6, 6, 3, 2, 17},
- {13, 21, 18, 11, 20, 29, 22, 15, 14, 20, 16, 12, 10, 14, 12, 10, 767},
- {281, 183, 37, 9, 171, 139, 37, 10, 35, 36, 15, 6, 9, 10, 6, 3, 37},
- {198, 164, 46, 13, 154, 147, 51, 16, 43, 49, 24, 10, 13, 16, 10, 5, 65},
- {1, 1, 93, 44, 1, 1, 72, 38, 86, 70, 43, 25, 40, 36, 25, 16, 432},
- {133, 141, 64, 28, 117, 122, 59, 27, 39, 48, 29, 15, 15, 20, 13, 8, 146},
- // LC3 Specification d09r01.pdf; Page 127 of 177
- {128, 125, 49, 18, 123, 134, 59, 23, 49, 59, 32, 15, 19, 24, 15, 9, 143},
- {1, 1, 23, 17, 1, 1, 23, 18, 20, 21, 18, 15, 15, 17, 14, 12, 807},
- {70, 96, 63, 38, 89, 112, 65, 36, 37, 47, 32, 20, 17, 23, 17, 12, 250},
- {55, 75, 45, 25, 68, 90, 58, 33, 39, 54, 39, 25, 22, 31, 24, 16, 325},
- {1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 993},
- {34, 51, 38, 24, 49, 69, 52, 35, 34, 47, 37, 27, 21, 31, 25, 19, 431},
- {30, 43, 32, 22, 43, 59, 45, 31, 30, 42, 34, 25, 19, 28, 23, 18, 500},
- {9, 15, 14, 13, 14, 22, 21, 18, 13, 20, 18, 16, 11, 17, 15, 14, 774},
- {30, 44, 31, 20, 41, 58, 42, 28, 28, 39, 30, 22, 18, 26, 21, 16, 530},
- {15, 23, 20, 15, 22, 33, 28, 22, 18, 26, 23, 18, 13, 20, 18, 15, 695},
- {11, 17, 16, 13, 17, 26, 23, 19, 15, 22, 20, 17, 12, 18, 16, 14, 748},
- {448, 171, 20, 4, 178, 105, 18, 4, 23, 20, 7, 2, 5, 5, 2, 1, 11},
- {332, 188, 29, 6, 186, 133, 29, 7, 30, 30, 11, 4, 6, 7, 4, 2, 20},
- {8, 13, 13, 11, 13, 20, 18, 16, 12, 17, 16, 13, 10, 14, 13, 12, 805},
- {239, 176, 42, 11, 163, 145, 44, 13, 39, 42, 19, 7, 11, 13, 7, 4, 49},
- {165, 145, 49, 16, 138, 139, 55, 20, 47, 54, 28, 12, 16, 20, 12, 7, 101},
- {3, 5, 5, 5, 5, 7, 7, 7, 4, 7, 7, 6, 4, 6, 6, 6, 934},
- {115, 122, 52, 22, 111, 125, 61, 27, 45, 57, 34, 17, 19, 25, 17, 10, 165},
- {107, 114, 51, 21, 106, 122, 61, 28, 46, 58, 35, 18, 20, 26, 18, 11, 182},
- {6, 10, 10, 9, 10, 15, 15, 14, 9, 14, 13, 12, 8, 12, 11, 10, 846},
- {72, 88, 50, 26, 84, 102, 60, 32, 41, 53, 36, 21, 20, 27, 20, 13, 279},
- {45, 63, 45, 30, 61, 83, 58, 36, 34, 47, 34, 23, 19, 27, 21, 15, 383},
- {1, 1, 7, 7, 1, 1, 8, 8, 6, 8, 7, 7, 6, 7, 7, 6, 936},
- {29, 44, 35, 24, 42, 62, 48, 34, 30, 43, 35, 26, 19, 29, 24, 19, 481},
- {20, 31, 25, 17, 30, 43, 34, 25, 22, 32, 26, 21, 16, 23, 20, 16, 623},
- {742, 103, 5, 1, 108, 38, 4, 1, 7, 5, 2, 1, 2, 1, 1, 1, 2},
- {42, 52, 27, 16, 49, 58, 36, 23, 27, 36, 26, 18, 17, 24, 19, 14, 540},
- {13, 20, 18, 15, 19, 29, 26, 21, 17, 25, 22, 18, 13, 19, 17, 15, 717},
- // LC3 Specification d09r01.pdf; Page 128 of 177
- {501, 169, 19, 4, 155, 88, 16, 4, 19, 16, 6, 2, 5, 4, 2, 1, 13},
- {445, 136, 22, 6, 158, 98, 23, 7, 31, 28, 10, 4, 9, 9, 5, 2, 31},
- {285, 157, 37, 10, 161, 129, 39, 12, 40, 42, 18, 7, 12, 14, 8, 4, 49},
- {349, 179, 33, 8, 162, 121, 31, 9, 31, 30, 12, 5, 8, 9, 5, 2, 30},
- {199, 156, 47, 15, 146, 137, 50, 17, 44, 49, 24, 10, 15, 17, 10, 6, 82},
- {141, 134, 50, 18, 128, 135, 58, 22, 48, 57, 31, 14, 18, 23, 14, 8, 125},
- {243, 194, 56, 17, 139, 126, 45, 16, 33, 36, 18, 8, 10, 12, 7, 4, 60},
- {91, 106, 51, 23, 99, 117, 63, 30, 45, 59, 37, 20, 20, 27, 19, 12, 205},
- {107, 94, 41, 20, 92, 97, 52, 28, 42, 53, 34, 20, 21, 29, 21, 14, 259},
- {168, 171, 68, 25, 121, 123, 55, 24, 34, 41, 24, 12, 13, 16, 11, 6, 112},
- {67, 80, 44, 23, 76, 94, 57, 31, 41, 54, 37, 23, 21, 30, 22, 15, 309},
- {46, 63, 39, 23, 58, 78, 52, 32, 36, 49, 37, 24, 21, 30, 24, 17, 395},
- {848, 70, 2, 1, 75, 16, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1},
- {36, 52, 35, 22, 48, 67, 48, 32, 32, 45, 35, 24, 20, 29, 23, 17, 459},
- {24, 37, 29, 20, 35, 51, 41, 29, 26, 38, 31, 24, 18, 27, 23, 18, 553},
- {85, 97, 48, 23, 91, 110, 61, 30, 45, 58, 37, 21, 21, 29, 20, 13, 235},
- {22, 33, 27, 20, 33, 48, 39, 30, 26, 37, 30, 23, 17, 25, 21, 17, 576},
- {1, 1, 54, 33, 1, 1, 49, 32, 49, 47, 35, 25, 30, 30, 24, 18, 594},
- {45, 64, 43, 25, 62, 81, 56, 35, 37, 51, 38, 26, 22, 31, 24, 18, 366},
- {247, 148, 38, 12, 154, 130, 42, 14, 44, 46, 21, 9, 15, 17, 9, 5, 73},
- {231, 136, 41, 15, 134, 119, 47, 19, 44, 49, 25, 12, 17, 20, 12, 7, 96}};
-short ac_spec_bits[64][17] = {
- {20480, 20480, 5220, 9042, 20480, 20480, 6619, 9892, 5289, 6619, 9105,
- 11629, 8982, 9892, 11629, 13677, 4977},
- {11940, 10854, 12109, 13677, 10742, 9812, 11090, 12288, 11348, 10240, 11348,
- 12683, 12109, 10854, 11629, 12902, 1197},
- {7886, 7120, 8982, 10970, 7496, 6815, 8334, 10150, 9437, 8535, 9656, 11216,
- 11348, 10431, 11348, 12479, 4051},
- {5485, 6099, 9168, 11940, 6311, 6262, 8640, 11090, 9233, 8640, 10334, 12479,
- 11781, 11090, 12479, 13988, 6009},
- {7886, 7804, 10150, 11940, 7886, 7685, 9368, 10854, 10061, 9300, 10431,
- 11629, 11629, 10742, 11485, 12479, 2763},
- // LC3 Specification d09r01.pdf; Page 129 of 177
- {9042, 8383, 10240, 11781, 8483, 8013, 9437, 10742, 10334, 9437, 10431,
- 11485, 11781, 10742, 11485, 12288, 2346},
- {5922, 6619, 9368, 11940, 6566, 6539, 8750, 10970, 9168, 8640, 10240, 12109,
- 11485, 10742, 11940, 13396, 5009},
- {12288, 11090, 11348, 12109, 11090, 9892, 10334, 10970, 11629, 10431, 10970,
- 11629, 12479, 11348, 11781, 12288, 1289},
- {1685, 5676, 13138, 18432, 5598, 7804, 13677, 18432, 12683, 13396, 17234,
- 20480, 17234, 17234, 20480, 20480, 15725},
- {2793, 5072, 10970, 15725, 5204, 6487, 11216, 15186, 10970, 11216, 14336,
- 17234, 15186, 15186, 17234, 18432, 12109},
- {12902, 11485, 11940, 13396, 11629, 10531, 11348, 12479, 12683, 11629,
- 12288, 13138, 13677, 12683, 13138, 13677, 854},
- {3821, 5088, 9812, 13988, 5289, 5901, 9812, 13677, 9976, 9892, 12479, 15186,
- 13988, 13677, 15186, 17234, 9812},
- {4856, 5412, 9168, 12902, 5598, 5736, 8863, 12288, 9368, 8982, 11090, 13677,
- 12902, 12288, 13677, 15725, 8147},
- {20480, 20480, 7088, 9300, 20480, 20480, 7844, 9733, 7320, 7928, 9368,
- 10970, 9581, 9892, 10970, 12288, 2550},
- {6031, 5859, 8192, 10635, 6410, 6286, 8433, 10742, 9656, 9042, 10531, 12479,
- 12479, 11629, 12902, 14336, 5756},
- {6144, 6215, 8982, 11940, 6262, 6009, 8433, 11216, 8982, 8433, 10240, 12479,
- 11781, 11090, 12479, 13988, 5817},
- {20480, 20480, 11216, 12109, 20480, 20480, 11216, 11940, 11629, 11485,
- 11940, 12479, 12479, 12109, 12683, 13138, 704},
- {7928, 6994, 8239, 9733, 7218, 6539, 8147, 9892, 9812, 9105, 10240, 11629,
- 12109, 11216, 12109, 13138, 4167},
- {8640, 7724, 9233, 10970, 8013, 7185, 8483, 10150, 9656, 8694, 9656, 10970,
- 11348, 10334, 11090, 12288, 3391},
- {20480, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432,
- 18432, 18432, 18432, 18432, 18432, 18432, 91},
- {10061, 8863, 9733, 11090, 8982, 7970, 8806, 9976, 10061, 9105, 9812, 10742,
- 11485, 10334, 10970, 11781, 2557},
- {10431, 9368, 10240, 11348, 9368, 8433, 9233, 10334, 10431, 9437, 10061,
- 10970, 11781, 10635, 11216, 11940, 2119},
- {13988, 12479, 12683, 12902, 12683, 11348, 11485, 11940, 12902, 11629,
- 11940, 12288, 13396, 12109, 12479, 12683, 828},
- {10431, 9300, 10334, 11629, 9508, 8483, 9437, 10635, 10635, 9656, 10431,
- 11348, 11940, 10854, 11485, 12288, 1946},
- {12479, 11216, 11629, 12479, 11348, 10150, 10635, 11348, 11940, 10854,
- 11216, 11940, 12902, 11629, 11940, 12479, 1146},
- {13396, 12109, 12288, 12902, 12109, 10854, 11216, 11781, 12479, 11348,
- 11629, 12109, 13138, 11940, 12288, 12683, 928},
- {2443, 5289, 11629, 16384, 5170, 6730, 11940, 16384, 11216, 11629, 14731,
- 18432, 15725, 15725, 18432, 20480, 13396},
- {3328, 5009, 10531, 15186, 5040, 6031, 10531, 14731, 10431, 10431, 13396,
- 16384, 15186, 14731, 16384, 18432, 11629},
- {14336, 12902, 12902, 13396, 12902, 11629, 11940, 12288, 13138, 12109,
- 12288, 12902, 13677, 12683, 12902, 13138, 711},
- // LC3 Specification d09r01.pdf; Page 130 of 177
- {4300, 5204, 9437, 13396, 5430, 5776, 9300, 12902, 9656, 9437, 11781, 14731,
- 13396, 12902, 14731, 16384, 8982},
- {5394, 5776, 8982, 12288, 5922, 5901, 8640, 11629, 9105, 8694, 10635, 13138,
- 12288, 11629, 13138, 14731, 6844},
- {17234, 15725, 15725, 15725, 15725, 14731, 14731, 14731, 16384, 14731,
- 14731, 15186, 16384, 15186, 15186, 15186, 272},
- {6461, 6286, 8806, 11348, 6566, 6215, 8334, 10742, 9233, 8535, 10061, 12109,
- 11781, 10970, 12109, 13677, 5394},
- {6674, 6487, 8863, 11485, 6702, 6286, 8334, 10635, 9168, 8483, 9976, 11940,
- 11629, 10854, 11940, 13396, 5105},
- {15186, 13677, 13677, 13988, 13677, 12479, 12479, 12683, 13988, 12683,
- 12902, 13138, 14336, 13138, 13396, 13677, 565},
- {7844, 7252, 8922, 10854, 7389, 6815, 8383, 10240, 9508, 8750, 9892, 11485,
- 11629, 10742, 11629, 12902, 3842},
- {9233, 8239, 9233, 10431, 8334, 7424, 8483, 9892, 10061, 9105, 10061, 11216,
- 11781, 10742, 11485, 12479, 2906},
- {20480, 20480, 14731, 14731, 20480, 20480, 14336, 14336, 15186, 14336,
- 14731, 14731, 15186, 14731, 14731, 15186, 266},
- {10531, 9300, 9976, 11090, 9437, 8286, 9042, 10061, 10431, 9368, 9976,
- 10854, 11781, 10531, 11090, 11781, 2233},
- {11629, 10334, 10970, 12109, 10431, 9368, 10061, 10970, 11348, 10240, 10854,
- 11485, 12288, 11216, 11629, 12288, 1469},
- {952, 6787, 15725, 20480, 6646, 9733, 16384, 20480, 14731, 15725, 18432,
- 20480, 18432, 20480, 20480, 20480, 18432},
- {9437, 8806, 10742, 12288, 8982, 8483, 9892, 11216, 10742, 9892, 10854,
- 11940, 12109, 11090, 11781, 12683, 1891},
- {12902, 11629, 11940, 12479, 11781, 10531, 10854, 11485, 12109, 10970,
- 11348, 11940, 12902, 11781, 12109, 12479, 1054},
- {2113, 5323, 11781, 16384, 5579, 7252, 12288, 16384, 11781, 12288, 15186,
- 18432, 15725, 16384, 18432, 20480, 12902},
- {2463, 5965, 11348, 15186, 5522, 6934, 11216, 14731, 10334, 10635, 13677,
- 16384, 13988, 13988, 15725, 18432, 10334},
- {3779, 5541, 9812, 13677, 5467, 6122, 9656, 13138, 9581, 9437, 11940, 14731,
- 13138, 12683, 14336, 16384, 8982},
- {3181, 5154, 10150, 14336, 5448, 6311, 10334, 13988, 10334, 10431, 13138,
- 15725, 14336, 13988, 15725, 18432, 10431},
- {4841, 5560, 9105, 12479, 5756, 5944, 8922, 12109, 9300, 8982, 11090, 13677,
- 12479, 12109, 13677, 15186, 7460},
- {5859, 6009, 8922, 11940, 6144, 5987, 8483, 11348, 9042, 8535, 10334, 12683,
- 11940, 11216, 12683, 14336, 6215},
- {4250, 4916, 8587, 12109, 5901, 6191, 9233, 12288, 10150, 9892, 11940,
- 14336, 13677, 13138, 14731, 16384, 8383},
- {7153, 6702, 8863, 11216, 6904, 6410, 8239, 10431, 9233, 8433, 9812, 11629,
- 11629, 10742, 11781, 13138, 4753},
- {6674, 7057, 9508, 11629, 7120, 6964, 8806, 10635, 9437, 8750, 10061, 11629,
- 11485, 10531, 11485, 12683, 4062},
- {5341, 5289, 8013, 10970, 6311, 6262, 8640, 11090, 10061, 9508, 11090,
- 13138, 12902, 12288, 13396, 15186, 6539},
- {8057, 7533, 9300, 11216, 7685, 7057, 8535, 10334, 9508, 8694, 9812, 11216,
- 11485, 10431, 11348, 12479, 3541},
- {9168, 8239, 9656, 11216, 8483, 7608, 8806, 10240, 9892, 8982, 9812, 11090,
- 11485, 10431, 11090, 12109, 2815},
- // LC3 Specification d09r01.pdf; Page 131 of 177
- {558, 7928, 18432, 20480, 7724, 12288, 20480, 20480, 18432, 20480, 20480,
- 20480, 20480, 20480, 20480, 20480, 20480},
- {9892, 8806, 9976, 11348, 9042, 8057, 9042, 10240, 10240, 9233, 9976, 11090,
- 11629, 10531, 11216, 12109, 2371},
- {11090, 9812, 10531, 11629, 9976, 8863, 9508, 10531, 10854, 9733, 10334,
- 11090, 11940, 10742, 11216, 11940, 1821},
- {7354, 6964, 9042, 11216, 7153, 6592, 8334, 10431, 9233, 8483, 9812, 11485,
- 11485, 10531, 11629, 12902, 4349},
- {11348, 10150, 10742, 11629, 10150, 9042, 9656, 10431, 10854, 9812, 10431,
- 11216, 12109, 10970, 11485, 12109, 1700},
- {20480, 20480, 8694, 10150, 20480, 20480, 8982, 10240, 8982, 9105, 9976,
- 10970, 10431, 10431, 11090, 11940, 1610},
- {9233, 8192, 9368, 10970, 8286, 7496, 8587, 9976, 9812, 8863, 9733, 10854,
- 11348, 10334, 11090, 11940, 3040},
- {4202, 5716, 9733, 13138, 5598, 6099, 9437, 12683, 9300, 9168, 11485, 13988,
- 12479, 12109, 13988, 15725, 7804},
- {4400, 5965, 9508, 12479, 6009, 6360, 9105, 11781, 9300, 8982, 10970, 13138,
- 12109, 11629, 13138, 14731, 6994}};
diff --git a/system/embdrv/lc3_dec/Common/Tables/SpectralDataTables.hpp b/system/embdrv/lc3_dec/Common/Tables/SpectralDataTables.hpp
deleted file mode 100644
index 6c031b6383..0000000000
--- a/system/embdrv/lc3_dec/Common/Tables/SpectralDataTables.hpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * SpectralDataTables.hpp
- *
- * 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.
- */
-
-// LC3 Specification d09r01.pdf
-// Section 5.7.6 Spectral data
-
-#ifndef SPECTRAL_DATA_TABLES_H_
-#define SPECTRAL_DATA_TABLES_H_
-
-extern unsigned char ac_spec_lookup[4096];
-extern short ac_spec_cumfreq[64][17];
-extern short ac_spec_freq[64][17];
-extern short ac_spec_bits[64][17];
-
-#endif // SPECTRAL_DATA_TABLES_H_
diff --git a/system/embdrv/lc3_dec/Common/Tables/TemporalNoiseShapingTables.cpp b/system/embdrv/lc3_dec/Common/Tables/TemporalNoiseShapingTables.cpp
deleted file mode 100644
index 4660663788..0000000000
--- a/system/embdrv/lc3_dec/Common/Tables/TemporalNoiseShapingTables.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * TemporalNoiseShapingTables.cpp
- *
- * 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.
- */
-
-// LC3 Specification d09r01.pdf
-// Section 5.7.4 Temporal Noise Shaping
-#include "TemporalNoiseShapingTables.hpp"
-
-// LC3 Specification d09r01.pdf; Page 109 of 177
-short ac_tns_order_bits[2][8] = {
- {17234, 13988, 11216, 8694, 6566, 4977, 3961, 3040},
- {12683, 9437, 6874, 5541, 5121, 5170, 5359, 5056}};
-short ac_tns_order_freq[2][8] = {{3, 9, 23, 54, 111, 190, 268, 366},
- {14, 42, 100, 157, 181, 178, 167, 185}};
-short ac_tns_order_cumfreq[2][8] = {{0, 3, 12, 35, 89, 200, 390, 658},
- {0, 14, 56, 156, 313, 494, 672, 839}};
-// LC3 Specification d09r01.pdf; Page 110 of 177
-short ac_tns_coef_bits[8][17] = {
- {20480, 15725, 12479, 10334, 8694, 7320, 6964, 6335, 5504, 5637, 6566, 6758,
- 8433, 11348, 15186, 20480, 20480},
- {20480, 20480, 20480, 20480, 12902, 9368, 7057, 5901, 5254, 5485, 5598,
- 6076, 7608, 10742, 15186, 20480, 20480},
- {20480, 20480, 20480, 20480, 13988, 9368, 6702, 4841, 4585, 4682, 5859,
- 7764, 12109, 20480, 20480, 20480, 20480},
- {20480, 20480, 20480, 20480, 18432, 13396, 8982, 4767, 3779, 3658, 6335,
- 9656, 13988, 20480, 20480, 20480, 20480},
- {20480, 20480, 20480, 20480, 20480, 14731, 9437, 4275, 3249, 3493, 8483,
- 13988, 17234, 20480, 20480, 20480, 20480},
- {20480, 20480, 20480, 20480, 20480, 20480, 12902, 4753, 3040, 2953, 9105,
- 15725, 20480, 20480, 20480, 20480, 20480},
- {20480, 20480, 20480, 20480, 20480, 20480, 12902, 3821, 3346, 3000, 12109,
- 20480, 20480, 20480, 20480, 20480, 20480},
- {20480, 20480, 20480, 20480, 20480, 20480, 15725, 3658, 20480, 1201, 10854,
- 18432, 20480, 20480, 20480, 20480, 20480}};
-short ac_tns_coef_freq[8][17] = {
- {1, 5, 15, 31, 54, 86, 97, 120, 159, 152, 111, 104, 59, 22, 6, 1, 1},
- {1, 1, 1, 1, 13, 43, 94, 139, 173, 160, 154, 131, 78, 27, 6, 1, 1},
- {1, 1, 1, 1, 9, 43, 106, 199, 217, 210, 141, 74, 17, 1, 1, 1, 1},
- {1, 1, 1, 1, 2, 11, 49, 204, 285, 297, 120, 39, 9, 1, 1, 1, 1},
- {1, 1, 1, 1, 1, 7, 42, 241, 341, 314, 58, 9, 3, 1, 1, 1, 1},
- {1, 1, 1, 1, 1, 1, 13, 205, 366, 377, 47, 5, 1, 1, 1, 1, 1},
- {1, 1, 1, 1, 1, 1, 13, 281, 330, 371, 17, 1, 1, 1, 1, 1, 1},
- {1, 1, 1, 1, 1, 1, 5, 297, 1, 682, 26, 2, 1, 1, 1, 1, 1}};
-short ac_tns_coef_cumfreq[8][17] = {{0, 1, 6, 21, 52, 106, 192, 289, 409, 568,
- 720, 831, 935, 994, 1016, 1022, 1023},
- {0, 1, 2, 3, 4, 17, 60, 154, 293, 466, 626,
- 780, 911, 989, 1016, 1022, 1023},
- {0, 1, 2, 3, 4, 13, 56, 162, 361, 578, 788,
- 929, 1003, 1020, 1021, 1022, 1023},
- {0, 1, 2, 3, 4, 6, 17, 66, 270, 555, 852,
- 972, 1011, 1020, 1021, 1022, 1023},
- {0, 1, 2, 3, 4, 5, 12, 54, 295, 636, 950,
- 1008, 1017, 1020, 1021, 1022, 1023},
- {0, 1, 2, 3, 4, 5, 6, 19, 224, 590, 967,
- 1014, 1019, 1020, 1021, 1022, 1023},
- {0, 1, 2, 3, 4, 5, 6, 19, 300, 630, 1001,
- 1018, 1019, 1020, 1021, 1022, 1023},
- {0, 1, 2, 3, 4, 5, 6, 11, 308, 309, 991,
- 1017, 1019, 1020, 1021, 1022, 1023}};
diff --git a/system/embdrv/lc3_dec/Common/Tables/TemporalNoiseShapingTables.hpp b/system/embdrv/lc3_dec/Common/Tables/TemporalNoiseShapingTables.hpp
deleted file mode 100644
index ca298b6320..0000000000
--- a/system/embdrv/lc3_dec/Common/Tables/TemporalNoiseShapingTables.hpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * TemporalNoiseShapingTables.hpp
- *
- * 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.
- */
-
-// LC3 Specification d09r01.pdf
-// Section 5.7.4 Temporal Noise Shaping
-
-#ifndef TEMPORAL_NOISE_SHAPING_TABLES_H_
-#define TEMPORAL_NOISE_SHAPING_TABLES_H_
-
-// LC3 Specification d09r01.pdf; Page 109 of 177
-extern short ac_tns_order_bits[2][8];
-extern short ac_tns_order_freq[2][8];
-extern short ac_tns_order_cumfreq[2][8];
-
-extern short ac_tns_coef_bits[8][17];
-extern short ac_tns_coef_freq[8][17];
-extern short ac_tns_coef_cumfreq[8][17];
-
-#endif // TEMPORAL_NOISE_SHAPING_TABLES_H_
diff --git a/system/embdrv/lc3_dec/Common/fft/fft.c b/system/embdrv/lc3_dec/Common/fft/fft.c
deleted file mode 100644
index d684302938..0000000000
--- a/system/embdrv/lc3_dec/Common/fft/fft.c
+++ /dev/null
@@ -1,677 +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.
- *
- ******************************************************************************/
-
-#include "fft.h"
-
-/* ----------------------------------------------------------------------------
- * FFT processing
- * -------------------------------------------------------------------------- */
-
-/**
- * Tables
- *
- * T_N[0..N-1] =
- * { cos(-2Pi i/N) + j sin(-2Pi i/N),
- * cos(-2Pi 2i/N) + j sin(-2Pi 2i/N) } , N=15, 45, 90
- *
- * T_N[0..N/2-1] =
- * cos(-2Pi i/N) + j sin(-2Pi i/N) , N=10, 20, ...
- */
-
-struct fft_bf2_twiddles {
- int n2;
- const struct fft_complex* t;
-};
-struct fft_bf3_twiddles {
- int n3;
- const struct fft_complex (*t)[2];
-};
-
-static const struct fft_bf2_twiddles twiddles_10 = {
- .n2 = 10 / 2,
- .t = (const struct fft_complex[]){
- {1.0000000e+00, -0.0000000e+00},
- {8.0901699e-01, -5.8778525e-01},
- {3.0901699e-01, -9.5105652e-01},
- {-3.0901699e-01, -9.5105652e-01},
- {-8.0901699e-01, -5.8778525e-01},
- }};
-
-static const struct fft_bf2_twiddles twiddles_20 = {
- .n2 = 20 / 2,
- .t = (const struct fft_complex[]){
- {1.0000000e+00, -0.0000000e+00},
- {9.5105652e-01, -3.0901699e-01},
- {8.0901699e-01, -5.8778525e-01},
- {5.8778525e-01, -8.0901699e-01},
- {3.0901699e-01, -9.5105652e-01},
- {6.1232340e-17, -1.0000000e+00},
- {-3.0901699e-01, -9.5105652e-01},
- {-5.8778525e-01, -8.0901699e-01},
- {-8.0901699e-01, -5.8778525e-01},
- {-9.5105652e-01, -3.0901699e-01},
- }};
-
-static const struct fft_bf2_twiddles twiddles_30 = {
- .n2 = 30 / 2,
- .t = (const struct fft_complex[]){
- {1.0000000e+00, -0.0000000e+00},
- {9.7814760e-01, -2.0791169e-01},
- {9.1354546e-01, -4.0673664e-01},
- {8.0901699e-01, -5.8778525e-01},
- {6.6913061e-01, -7.4314483e-01},
- {5.0000000e-01, -8.6602540e-01},
- {3.0901699e-01, -9.5105652e-01},
- {1.0452846e-01, -9.9452190e-01},
- {-1.0452846e-01, -9.9452190e-01},
- {-3.0901699e-01, -9.5105652e-01},
- {-5.0000000e-01, -8.6602540e-01},
- {-6.6913061e-01, -7.4314483e-01},
- {-8.0901699e-01, -5.8778525e-01},
- {-9.1354546e-01, -4.0673664e-01},
- {-9.7814760e-01, -2.0791169e-01},
- }};
-
-static const struct fft_bf2_twiddles twiddles_40 = {
- .n2 = 40 / 2,
- .t = (const struct fft_complex[]){
- {1.0000000e+00, -0.0000000e+00}, {9.8768834e-01, -1.5643447e-01},
- {9.5105652e-01, -3.0901699e-01}, {8.9100652e-01, -4.5399050e-01},
- {8.0901699e-01, -5.8778525e-01}, {7.0710678e-01, -7.0710678e-01},
- {5.8778525e-01, -8.0901699e-01}, {4.5399050e-01, -8.9100652e-01},
- {3.0901699e-01, -9.5105652e-01}, {1.5643447e-01, -9.8768834e-01},
- {6.1232340e-17, -1.0000000e+00}, {-1.5643447e-01, -9.8768834e-01},
- {-3.0901699e-01, -9.5105652e-01}, {-4.5399050e-01, -8.9100652e-01},
- {-5.8778525e-01, -8.0901699e-01}, {-7.0710678e-01, -7.0710678e-01},
- {-8.0901699e-01, -5.8778525e-01}, {-8.9100652e-01, -4.5399050e-01},
- {-9.5105652e-01, -3.0901699e-01}, {-9.8768834e-01, -1.5643447e-01},
- }};
-
-static const struct fft_bf2_twiddles twiddles_60 = {
- .n2 = 60 / 2,
- .t = (const struct fft_complex[]){
- {1.0000000e+00, -0.0000000e+00}, {9.9452190e-01, -1.0452846e-01},
- {9.7814760e-01, -2.0791169e-01}, {9.5105652e-01, -3.0901699e-01},
- {9.1354546e-01, -4.0673664e-01}, {8.6602540e-01, -5.0000000e-01},
- {8.0901699e-01, -5.8778525e-01}, {7.4314483e-01, -6.6913061e-01},
- {6.6913061e-01, -7.4314483e-01}, {5.8778525e-01, -8.0901699e-01},
- {5.0000000e-01, -8.6602540e-01}, {4.0673664e-01, -9.1354546e-01},
- {3.0901699e-01, -9.5105652e-01}, {2.0791169e-01, -9.7814760e-01},
- {1.0452846e-01, -9.9452190e-01}, {2.8327694e-16, -1.0000000e+00},
- {-1.0452846e-01, -9.9452190e-01}, {-2.0791169e-01, -9.7814760e-01},
- {-3.0901699e-01, -9.5105652e-01}, {-4.0673664e-01, -9.1354546e-01},
- {-5.0000000e-01, -8.6602540e-01}, {-5.8778525e-01, -8.0901699e-01},
- {-6.6913061e-01, -7.4314483e-01}, {-7.4314483e-01, -6.6913061e-01},
- {-8.0901699e-01, -5.8778525e-01}, {-8.6602540e-01, -5.0000000e-01},
- {-9.1354546e-01, -4.0673664e-01}, {-9.5105652e-01, -3.0901699e-01},
- {-9.7814760e-01, -2.0791169e-01}, {-9.9452190e-01, -1.0452846e-01},
- }};
-
-static const struct fft_bf2_twiddles twiddles_80 = {
- .n2 = 80 / 2,
- .t = (const struct fft_complex[]){
- {1.0000000e+00, -0.0000000e+00}, {9.9691733e-01, -7.8459096e-02},
- {9.8768834e-01, -1.5643447e-01}, {9.7236992e-01, -2.3344536e-01},
- {9.5105652e-01, -3.0901699e-01}, {9.2387953e-01, -3.8268343e-01},
- {8.9100652e-01, -4.5399050e-01}, {8.5264016e-01, -5.2249856e-01},
- {8.0901699e-01, -5.8778525e-01}, {7.6040597e-01, -6.4944805e-01},
- {7.0710678e-01, -7.0710678e-01}, {6.4944805e-01, -7.6040597e-01},
- {5.8778525e-01, -8.0901699e-01}, {5.2249856e-01, -8.5264016e-01},
- {4.5399050e-01, -8.9100652e-01}, {3.8268343e-01, -9.2387953e-01},
- {3.0901699e-01, -9.5105652e-01}, {2.3344536e-01, -9.7236992e-01},
- {1.5643447e-01, -9.8768834e-01}, {7.8459096e-02, -9.9691733e-01},
- {6.1232340e-17, -1.0000000e+00}, {-7.8459096e-02, -9.9691733e-01},
- {-1.5643447e-01, -9.8768834e-01}, {-2.3344536e-01, -9.7236992e-01},
- {-3.0901699e-01, -9.5105652e-01}, {-3.8268343e-01, -9.2387953e-01},
- {-4.5399050e-01, -8.9100652e-01}, {-5.2249856e-01, -8.5264016e-01},
- {-5.8778525e-01, -8.0901699e-01}, {-6.4944805e-01, -7.6040597e-01},
- {-7.0710678e-01, -7.0710678e-01}, {-7.6040597e-01, -6.4944805e-01},
- {-8.0901699e-01, -5.8778525e-01}, {-8.5264016e-01, -5.2249856e-01},
- {-8.9100652e-01, -4.5399050e-01}, {-9.2387953e-01, -3.8268343e-01},
- {-9.5105652e-01, -3.0901699e-01}, {-9.7236992e-01, -2.3344536e-01},
- {-9.8768834e-01, -1.5643447e-01}, {-9.9691733e-01, -7.8459096e-02},
- }};
-
-static const struct fft_bf2_twiddles twiddles_90 = {
- .n2 = 90 / 2,
- .t = (const struct fft_complex[]){
- {1.0000000e+00, -0.0000000e+00}, {9.9756405e-01, -6.9756474e-02},
- {9.9026807e-01, -1.3917310e-01}, {9.7814760e-01, -2.0791169e-01},
- {9.6126170e-01, -2.7563736e-01}, {9.3969262e-01, -3.4202014e-01},
- {9.1354546e-01, -4.0673664e-01}, {8.8294759e-01, -4.6947156e-01},
- {8.4804810e-01, -5.2991926e-01}, {8.0901699e-01, -5.8778525e-01},
- {7.6604444e-01, -6.4278761e-01}, {7.1933980e-01, -6.9465837e-01},
- {6.6913061e-01, -7.4314483e-01}, {6.1566148e-01, -7.8801075e-01},
- {5.5919290e-01, -8.2903757e-01}, {5.0000000e-01, -8.6602540e-01},
- {4.3837115e-01, -8.9879405e-01}, {3.7460659e-01, -9.2718385e-01},
- {3.0901699e-01, -9.5105652e-01}, {2.4192190e-01, -9.7029573e-01},
- {1.7364818e-01, -9.8480775e-01}, {1.0452846e-01, -9.9452190e-01},
- {3.4899497e-02, -9.9939083e-01}, {-3.4899497e-02, -9.9939083e-01},
- {-1.0452846e-01, -9.9452190e-01}, {-1.7364818e-01, -9.8480775e-01},
- {-2.4192190e-01, -9.7029573e-01}, {-3.0901699e-01, -9.5105652e-01},
- {-3.7460659e-01, -9.2718385e-01}, {-4.3837115e-01, -8.9879405e-01},
- {-5.0000000e-01, -8.6602540e-01}, {-5.5919290e-01, -8.2903757e-01},
- {-6.1566148e-01, -7.8801075e-01}, {-6.6913061e-01, -7.4314483e-01},
- {-7.1933980e-01, -6.9465837e-01}, {-7.6604444e-01, -6.4278761e-01},
- {-8.0901699e-01, -5.8778525e-01}, {-8.4804810e-01, -5.2991926e-01},
- {-8.8294759e-01, -4.6947156e-01}, {-9.1354546e-01, -4.0673664e-01},
- {-9.3969262e-01, -3.4202014e-01}, {-9.6126170e-01, -2.7563736e-01},
- {-9.7814760e-01, -2.0791169e-01}, {-9.9026807e-01, -1.3917310e-01},
- {-9.9756405e-01, -6.9756474e-02},
- }};
-
-static const struct fft_bf2_twiddles twiddles_120 = {
- .n2 = 120 / 2,
- .t = (const struct fft_complex[]){
- {1.0000000e+00, -0.0000000e+00}, {9.9862953e-01, -5.2335956e-02},
- {9.9452190e-01, -1.0452846e-01}, {9.8768834e-01, -1.5643447e-01},
- {9.7814760e-01, -2.0791169e-01}, {9.6592583e-01, -2.5881905e-01},
- {9.5105652e-01, -3.0901699e-01}, {9.3358043e-01, -3.5836795e-01},
- {9.1354546e-01, -4.0673664e-01}, {8.9100652e-01, -4.5399050e-01},
- {8.6602540e-01, -5.0000000e-01}, {8.3867057e-01, -5.4463904e-01},
- {8.0901699e-01, -5.8778525e-01}, {7.7714596e-01, -6.2932039e-01},
- {7.4314483e-01, -6.6913061e-01}, {7.0710678e-01, -7.0710678e-01},
- {6.6913061e-01, -7.4314483e-01}, {6.2932039e-01, -7.7714596e-01},
- {5.8778525e-01, -8.0901699e-01}, {5.4463904e-01, -8.3867057e-01},
- {5.0000000e-01, -8.6602540e-01}, {4.5399050e-01, -8.9100652e-01},
- {4.0673664e-01, -9.1354546e-01}, {3.5836795e-01, -9.3358043e-01},
- {3.0901699e-01, -9.5105652e-01}, {2.5881905e-01, -9.6592583e-01},
- {2.0791169e-01, -9.7814760e-01}, {1.5643447e-01, -9.8768834e-01},
- {1.0452846e-01, -9.9452190e-01}, {5.2335956e-02, -9.9862953e-01},
- {2.8327694e-16, -1.0000000e+00}, {-5.2335956e-02, -9.9862953e-01},
- {-1.0452846e-01, -9.9452190e-01}, {-1.5643447e-01, -9.8768834e-01},
- {-2.0791169e-01, -9.7814760e-01}, {-2.5881905e-01, -9.6592583e-01},
- {-3.0901699e-01, -9.5105652e-01}, {-3.5836795e-01, -9.3358043e-01},
- {-4.0673664e-01, -9.1354546e-01}, {-4.5399050e-01, -8.9100652e-01},
- {-5.0000000e-01, -8.6602540e-01}, {-5.4463904e-01, -8.3867057e-01},
- {-5.8778525e-01, -8.0901699e-01}, {-6.2932039e-01, -7.7714596e-01},
- {-6.6913061e-01, -7.4314483e-01}, {-7.0710678e-01, -7.0710678e-01},
- {-7.4314483e-01, -6.6913061e-01}, {-7.7714596e-01, -6.2932039e-01},
- {-8.0901699e-01, -5.8778525e-01}, {-8.3867057e-01, -5.4463904e-01},
- {-8.6602540e-01, -5.0000000e-01}, {-8.9100652e-01, -4.5399050e-01},
- {-9.1354546e-01, -4.0673664e-01}, {-9.3358043e-01, -3.5836795e-01},
- {-9.5105652e-01, -3.0901699e-01}, {-9.6592583e-01, -2.5881905e-01},
- {-9.7814760e-01, -2.0791169e-01}, {-9.8768834e-01, -1.5643447e-01},
- {-9.9452190e-01, -1.0452846e-01}, {-9.9862953e-01, -5.2335956e-02},
- }};
-
-static const struct fft_bf2_twiddles twiddles_160 = {
- .n2 = 160 / 2,
- .t = (const struct fft_complex[]){
- {1.0000000e+00, -0.0000000e+00}, {9.9922904e-01, -3.9259816e-02},
- {9.9691733e-01, -7.8459096e-02}, {9.9306846e-01, -1.1753740e-01},
- {9.8768834e-01, -1.5643447e-01}, {9.8078528e-01, -1.9509032e-01},
- {9.7236992e-01, -2.3344536e-01}, {9.6245524e-01, -2.7144045e-01},
- {9.5105652e-01, -3.0901699e-01}, {9.3819134e-01, -3.4611706e-01},
- {9.2387953e-01, -3.8268343e-01}, {9.0814317e-01, -4.1865974e-01},
- {8.9100652e-01, -4.5399050e-01}, {8.7249601e-01, -4.8862124e-01},
- {8.5264016e-01, -5.2249856e-01}, {8.3146961e-01, -5.5557023e-01},
- {8.0901699e-01, -5.8778525e-01}, {7.8531693e-01, -6.1909395e-01},
- {7.6040597e-01, -6.4944805e-01}, {7.3432251e-01, -6.7880075e-01},
- {7.0710678e-01, -7.0710678e-01}, {6.7880075e-01, -7.3432251e-01},
- {6.4944805e-01, -7.6040597e-01}, {6.1909395e-01, -7.8531693e-01},
- {5.8778525e-01, -8.0901699e-01}, {5.5557023e-01, -8.3146961e-01},
- {5.2249856e-01, -8.5264016e-01}, {4.8862124e-01, -8.7249601e-01},
- {4.5399050e-01, -8.9100652e-01}, {4.1865974e-01, -9.0814317e-01},
- {3.8268343e-01, -9.2387953e-01}, {3.4611706e-01, -9.3819134e-01},
- {3.0901699e-01, -9.5105652e-01}, {2.7144045e-01, -9.6245524e-01},
- {2.3344536e-01, -9.7236992e-01}, {1.9509032e-01, -9.8078528e-01},
- {1.5643447e-01, -9.8768834e-01}, {1.1753740e-01, -9.9306846e-01},
- {7.8459096e-02, -9.9691733e-01}, {3.9259816e-02, -9.9922904e-01},
- {6.1232340e-17, -1.0000000e+00}, {-3.9259816e-02, -9.9922904e-01},
- {-7.8459096e-02, -9.9691733e-01}, {-1.1753740e-01, -9.9306846e-01},
- {-1.5643447e-01, -9.8768834e-01}, {-1.9509032e-01, -9.8078528e-01},
- {-2.3344536e-01, -9.7236992e-01}, {-2.7144045e-01, -9.6245524e-01},
- {-3.0901699e-01, -9.5105652e-01}, {-3.4611706e-01, -9.3819134e-01},
- {-3.8268343e-01, -9.2387953e-01}, {-4.1865974e-01, -9.0814317e-01},
- {-4.5399050e-01, -8.9100652e-01}, {-4.8862124e-01, -8.7249601e-01},
- {-5.2249856e-01, -8.5264016e-01}, {-5.5557023e-01, -8.3146961e-01},
- {-5.8778525e-01, -8.0901699e-01}, {-6.1909395e-01, -7.8531693e-01},
- {-6.4944805e-01, -7.6040597e-01}, {-6.7880075e-01, -7.3432251e-01},
- {-7.0710678e-01, -7.0710678e-01}, {-7.3432251e-01, -6.7880075e-01},
- {-7.6040597e-01, -6.4944805e-01}, {-7.8531693e-01, -6.1909395e-01},
- {-8.0901699e-01, -5.8778525e-01}, {-8.3146961e-01, -5.5557023e-01},
- {-8.5264016e-01, -5.2249856e-01}, {-8.7249601e-01, -4.8862124e-01},
- {-8.9100652e-01, -4.5399050e-01}, {-9.0814317e-01, -4.1865974e-01},
- {-9.2387953e-01, -3.8268343e-01}, {-9.3819134e-01, -3.4611706e-01},
- {-9.5105652e-01, -3.0901699e-01}, {-9.6245524e-01, -2.7144045e-01},
- {-9.7236992e-01, -2.3344536e-01}, {-9.8078528e-01, -1.9509032e-01},
- {-9.8768834e-01, -1.5643447e-01}, {-9.9306846e-01, -1.1753740e-01},
- {-9.9691733e-01, -7.8459096e-02}, {-9.9922904e-01, -3.9259816e-02},
- }};
-
-static const struct fft_bf2_twiddles twiddles_180 = {
- .n2 = 180 / 2,
- .t = (const struct fft_complex[]){
- {1.0000000e+00, -0.0000000e+00}, {9.9939083e-01, -3.4899497e-02},
- {9.9756405e-01, -6.9756474e-02}, {9.9452190e-01, -1.0452846e-01},
- {9.9026807e-01, -1.3917310e-01}, {9.8480775e-01, -1.7364818e-01},
- {9.7814760e-01, -2.0791169e-01}, {9.7029573e-01, -2.4192190e-01},
- {9.6126170e-01, -2.7563736e-01}, {9.5105652e-01, -3.0901699e-01},
- {9.3969262e-01, -3.4202014e-01}, {9.2718385e-01, -3.7460659e-01},
- {9.1354546e-01, -4.0673664e-01}, {8.9879405e-01, -4.3837115e-01},
- {8.8294759e-01, -4.6947156e-01}, {8.6602540e-01, -5.0000000e-01},
- {8.4804810e-01, -5.2991926e-01}, {8.2903757e-01, -5.5919290e-01},
- {8.0901699e-01, -5.8778525e-01}, {7.8801075e-01, -6.1566148e-01},
- {7.6604444e-01, -6.4278761e-01}, {7.4314483e-01, -6.6913061e-01},
- {7.1933980e-01, -6.9465837e-01}, {6.9465837e-01, -7.1933980e-01},
- {6.6913061e-01, -7.4314483e-01}, {6.4278761e-01, -7.6604444e-01},
- {6.1566148e-01, -7.8801075e-01}, {5.8778525e-01, -8.0901699e-01},
- {5.5919290e-01, -8.2903757e-01}, {5.2991926e-01, -8.4804810e-01},
- {5.0000000e-01, -8.6602540e-01}, {4.6947156e-01, -8.8294759e-01},
- {4.3837115e-01, -8.9879405e-01}, {4.0673664e-01, -9.1354546e-01},
- {3.7460659e-01, -9.2718385e-01}, {3.4202014e-01, -9.3969262e-01},
- {3.0901699e-01, -9.5105652e-01}, {2.7563736e-01, -9.6126170e-01},
- {2.4192190e-01, -9.7029573e-01}, {2.0791169e-01, -9.7814760e-01},
- {1.7364818e-01, -9.8480775e-01}, {1.3917310e-01, -9.9026807e-01},
- {1.0452846e-01, -9.9452190e-01}, {6.9756474e-02, -9.9756405e-01},
- {3.4899497e-02, -9.9939083e-01}, {6.1232340e-17, -1.0000000e+00},
- {-3.4899497e-02, -9.9939083e-01}, {-6.9756474e-02, -9.9756405e-01},
- {-1.0452846e-01, -9.9452190e-01}, {-1.3917310e-01, -9.9026807e-01},
- {-1.7364818e-01, -9.8480775e-01}, {-2.0791169e-01, -9.7814760e-01},
- {-2.4192190e-01, -9.7029573e-01}, {-2.7563736e-01, -9.6126170e-01},
- {-3.0901699e-01, -9.5105652e-01}, {-3.4202014e-01, -9.3969262e-01},
- {-3.7460659e-01, -9.2718385e-01}, {-4.0673664e-01, -9.1354546e-01},
- {-4.3837115e-01, -8.9879405e-01}, {-4.6947156e-01, -8.8294759e-01},
- {-5.0000000e-01, -8.6602540e-01}, {-5.2991926e-01, -8.4804810e-01},
- {-5.5919290e-01, -8.2903757e-01}, {-5.8778525e-01, -8.0901699e-01},
- {-6.1566148e-01, -7.8801075e-01}, {-6.4278761e-01, -7.6604444e-01},
- {-6.6913061e-01, -7.4314483e-01}, {-6.9465837e-01, -7.1933980e-01},
- {-7.1933980e-01, -6.9465837e-01}, {-7.4314483e-01, -6.6913061e-01},
- {-7.6604444e-01, -6.4278761e-01}, {-7.8801075e-01, -6.1566148e-01},
- {-8.0901699e-01, -5.8778525e-01}, {-8.2903757e-01, -5.5919290e-01},
- {-8.4804810e-01, -5.2991926e-01}, {-8.6602540e-01, -5.0000000e-01},
- {-8.8294759e-01, -4.6947156e-01}, {-8.9879405e-01, -4.3837115e-01},
- {-9.1354546e-01, -4.0673664e-01}, {-9.2718385e-01, -3.7460659e-01},
- {-9.3969262e-01, -3.4202014e-01}, {-9.5105652e-01, -3.0901699e-01},
- {-9.6126170e-01, -2.7563736e-01}, {-9.7029573e-01, -2.4192190e-01},
- {-9.7814760e-01, -2.0791169e-01}, {-9.8480775e-01, -1.7364818e-01},
- {-9.9026807e-01, -1.3917310e-01}, {-9.9452190e-01, -1.0452846e-01},
- {-9.9756405e-01, -6.9756474e-02}, {-9.9939083e-01, -3.4899497e-02},
- }};
-
-static const struct fft_bf2_twiddles twiddles_240 = {
- .n2 = 240 / 2,
- .t = (const struct fft_complex[]){
- {1.0000000e+00, -0.0000000e+00}, {9.9965732e-01, -2.6176948e-02},
- {9.9862953e-01, -5.2335956e-02}, {9.9691733e-01, -7.8459096e-02},
- {9.9452190e-01, -1.0452846e-01}, {9.9144486e-01, -1.3052619e-01},
- {9.8768834e-01, -1.5643447e-01}, {9.8325491e-01, -1.8223553e-01},
- {9.7814760e-01, -2.0791169e-01}, {9.7236992e-01, -2.3344536e-01},
- {9.6592583e-01, -2.5881905e-01}, {9.5881973e-01, -2.8401534e-01},
- {9.5105652e-01, -3.0901699e-01}, {9.4264149e-01, -3.3380686e-01},
- {9.3358043e-01, -3.5836795e-01}, {9.2387953e-01, -3.8268343e-01},
- {9.1354546e-01, -4.0673664e-01}, {9.0258528e-01, -4.3051110e-01},
- {8.9100652e-01, -4.5399050e-01}, {8.7881711e-01, -4.7715876e-01},
- {8.6602540e-01, -5.0000000e-01}, {8.5264016e-01, -5.2249856e-01},
- {8.3867057e-01, -5.4463904e-01}, {8.2412619e-01, -5.6640624e-01},
- {8.0901699e-01, -5.8778525e-01}, {7.9335334e-01, -6.0876143e-01},
- {7.7714596e-01, -6.2932039e-01}, {7.6040597e-01, -6.4944805e-01},
- {7.4314483e-01, -6.6913061e-01}, {7.2537437e-01, -6.8835458e-01},
- {7.0710678e-01, -7.0710678e-01}, {6.8835458e-01, -7.2537437e-01},
- {6.6913061e-01, -7.4314483e-01}, {6.4944805e-01, -7.6040597e-01},
- {6.2932039e-01, -7.7714596e-01}, {6.0876143e-01, -7.9335334e-01},
- {5.8778525e-01, -8.0901699e-01}, {5.6640624e-01, -8.2412619e-01},
- {5.4463904e-01, -8.3867057e-01}, {5.2249856e-01, -8.5264016e-01},
- {5.0000000e-01, -8.6602540e-01}, {4.7715876e-01, -8.7881711e-01},
- {4.5399050e-01, -8.9100652e-01}, {4.3051110e-01, -9.0258528e-01},
- {4.0673664e-01, -9.1354546e-01}, {3.8268343e-01, -9.2387953e-01},
- {3.5836795e-01, -9.3358043e-01}, {3.3380686e-01, -9.4264149e-01},
- {3.0901699e-01, -9.5105652e-01}, {2.8401534e-01, -9.5881973e-01},
- {2.5881905e-01, -9.6592583e-01}, {2.3344536e-01, -9.7236992e-01},
- {2.0791169e-01, -9.7814760e-01}, {1.8223553e-01, -9.8325491e-01},
- {1.5643447e-01, -9.8768834e-01}, {1.3052619e-01, -9.9144486e-01},
- {1.0452846e-01, -9.9452190e-01}, {7.8459096e-02, -9.9691733e-01},
- {5.2335956e-02, -9.9862953e-01}, {2.6176948e-02, -9.9965732e-01},
- {2.8327694e-16, -1.0000000e+00}, {-2.6176948e-02, -9.9965732e-01},
- {-5.2335956e-02, -9.9862953e-01}, {-7.8459096e-02, -9.9691733e-01},
- {-1.0452846e-01, -9.9452190e-01}, {-1.3052619e-01, -9.9144486e-01},
- {-1.5643447e-01, -9.8768834e-01}, {-1.8223553e-01, -9.8325491e-01},
- {-2.0791169e-01, -9.7814760e-01}, {-2.3344536e-01, -9.7236992e-01},
- {-2.5881905e-01, -9.6592583e-01}, {-2.8401534e-01, -9.5881973e-01},
- {-3.0901699e-01, -9.5105652e-01}, {-3.3380686e-01, -9.4264149e-01},
- {-3.5836795e-01, -9.3358043e-01}, {-3.8268343e-01, -9.2387953e-01},
- {-4.0673664e-01, -9.1354546e-01}, {-4.3051110e-01, -9.0258528e-01},
- {-4.5399050e-01, -8.9100652e-01}, {-4.7715876e-01, -8.7881711e-01},
- {-5.0000000e-01, -8.6602540e-01}, {-5.2249856e-01, -8.5264016e-01},
- {-5.4463904e-01, -8.3867057e-01}, {-5.6640624e-01, -8.2412619e-01},
- {-5.8778525e-01, -8.0901699e-01}, {-6.0876143e-01, -7.9335334e-01},
- {-6.2932039e-01, -7.7714596e-01}, {-6.4944805e-01, -7.6040597e-01},
- {-6.6913061e-01, -7.4314483e-01}, {-6.8835458e-01, -7.2537437e-01},
- {-7.0710678e-01, -7.0710678e-01}, {-7.2537437e-01, -6.8835458e-01},
- {-7.4314483e-01, -6.6913061e-01}, {-7.6040597e-01, -6.4944805e-01},
- {-7.7714596e-01, -6.2932039e-01}, {-7.9335334e-01, -6.0876143e-01},
- {-8.0901699e-01, -5.8778525e-01}, {-8.2412619e-01, -5.6640624e-01},
- {-8.3867057e-01, -5.4463904e-01}, {-8.5264016e-01, -5.2249856e-01},
- {-8.6602540e-01, -5.0000000e-01}, {-8.7881711e-01, -4.7715876e-01},
- {-8.9100652e-01, -4.5399050e-01}, {-9.0258528e-01, -4.3051110e-01},
- {-9.1354546e-01, -4.0673664e-01}, {-9.2387953e-01, -3.8268343e-01},
- {-9.3358043e-01, -3.5836795e-01}, {-9.4264149e-01, -3.3380686e-01},
- {-9.5105652e-01, -3.0901699e-01}, {-9.5881973e-01, -2.8401534e-01},
- {-9.6592583e-01, -2.5881905e-01}, {-9.7236992e-01, -2.3344536e-01},
- {-9.7814760e-01, -2.0791169e-01}, {-9.8325491e-01, -1.8223553e-01},
- {-9.8768834e-01, -1.5643447e-01}, {-9.9144486e-01, -1.3052619e-01},
- {-9.9452190e-01, -1.0452846e-01}, {-9.9691733e-01, -7.8459096e-02},
- {-9.9862953e-01, -5.2335956e-02}, {-9.9965732e-01, -2.6176948e-02},
- }};
-
-static const struct fft_bf3_twiddles twiddles_15 = {
- .n3 = 15 / 3,
- .t = (const struct fft_complex[][2]){
- {{1.0000000e+0, -0.0000000e+0}, {1.0000000e+0, -0.0000000e+0}},
- {{9.1354546e-1, -4.0673664e-1}, {6.6913061e-1, -7.4314483e-1}},
- {{6.6913061e-1, -7.4314483e-1}, {-1.0452846e-1, -9.9452190e-1}},
- {{3.0901699e-1, -9.5105652e-1}, {-8.0901699e-1, -5.8778525e-1}},
- {{-1.0452846e-1, -9.9452190e-1}, {-9.7814760e-1, 2.0791169e-1}},
- {{-5.0000000e-1, -8.6602540e-1}, {-5.0000000e-1, 8.6602540e-1}},
- {{-8.0901699e-1, -5.8778525e-1}, {3.0901699e-1, 9.5105652e-1}},
- {{-9.7814760e-1, -2.0791169e-1}, {9.1354546e-1, 4.0673664e-1}},
- {{-9.7814760e-1, 2.0791169e-1}, {9.1354546e-1, -4.0673664e-1}},
- {{-8.0901699e-1, 5.8778525e-1}, {3.0901699e-1, -9.5105652e-1}},
- {{-5.0000000e-1, 8.6602540e-1}, {-5.0000000e-1, -8.6602540e-1}},
- {{-1.0452846e-1, 9.9452190e-1}, {-9.7814760e-1, -2.0791169e-1}},
- {{3.0901699e-1, 9.5105652e-1}, {-8.0901699e-1, 5.8778525e-1}},
- {{6.6913061e-1, 7.4314483e-1}, {-1.0452846e-1, 9.9452190e-1}},
- {{9.1354546e-1, 4.0673664e-1}, {6.6913061e-1, 7.4314483e-1}},
- }};
-
-static const struct fft_bf3_twiddles twiddles_45 = {
- .n3 = 45 / 3,
- .t = (const struct fft_complex[][2]){
- {{1.0000000e+0, -0.0000000e+0}, {1.0000000e+0, -0.0000000e+0}},
- {{9.9026807e-1, -1.3917310e-1}, {9.6126170e-1, -2.7563736e-1}},
- {{9.6126170e-1, -2.7563736e-1}, {8.4804810e-1, -5.2991926e-1}},
- {{9.1354546e-1, -4.0673664e-1}, {6.6913061e-1, -7.4314483e-1}},
- {{8.4804810e-1, -5.2991926e-1}, {4.3837115e-1, -8.9879405e-1}},
- {{7.6604444e-1, -6.4278761e-1}, {1.7364818e-1, -9.8480775e-1}},
- {{6.6913061e-1, -7.4314483e-1}, {-1.0452846e-1, -9.9452190e-1}},
- {{5.5919290e-1, -8.2903757e-1}, {-3.7460659e-1, -9.2718385e-1}},
- {{4.3837115e-1, -8.9879405e-1}, {-6.1566148e-1, -7.8801075e-1}},
- {{3.0901699e-1, -9.5105652e-1}, {-8.0901699e-1, -5.8778525e-1}},
- {{1.7364818e-1, -9.8480775e-1}, {-9.3969262e-1, -3.4202014e-1}},
- {{3.4899497e-2, -9.9939083e-1}, {-9.9756405e-1, -6.9756474e-2}},
- {{-1.0452846e-1, -9.9452190e-1}, {-9.7814760e-1, 2.0791169e-1}},
- {{-2.4192190e-1, -9.7029573e-1}, {-8.8294759e-1, 4.6947156e-1}},
- {{-3.7460659e-1, -9.2718385e-1}, {-7.1933980e-1, 6.9465837e-1}},
- {{-5.0000000e-1, -8.6602540e-1}, {-5.0000000e-1, 8.6602540e-1}},
- {{-6.1566148e-1, -7.8801075e-1}, {-2.4192190e-1, 9.7029573e-1}},
- {{-7.1933980e-1, -6.9465837e-1}, {3.4899497e-2, 9.9939083e-1}},
- {{-8.0901699e-1, -5.8778525e-1}, {3.0901699e-1, 9.5105652e-1}},
- {{-8.8294759e-1, -4.6947156e-1}, {5.5919290e-1, 8.2903757e-1}},
- {{-9.3969262e-1, -3.4202014e-1}, {7.6604444e-1, 6.4278761e-1}},
- {{-9.7814760e-1, -2.0791169e-1}, {9.1354546e-1, 4.0673664e-1}},
- {{-9.9756405e-1, -6.9756474e-2}, {9.9026807e-1, 1.3917310e-1}},
- {{-9.9756405e-1, 6.9756474e-2}, {9.9026807e-1, -1.3917310e-1}},
- {{-9.7814760e-1, 2.0791169e-1}, {9.1354546e-1, -4.0673664e-1}},
- {{-9.3969262e-1, 3.4202014e-1}, {7.6604444e-1, -6.4278761e-1}},
- {{-8.8294759e-1, 4.6947156e-1}, {5.5919290e-1, -8.2903757e-1}},
- {{-8.0901699e-1, 5.8778525e-1}, {3.0901699e-1, -9.5105652e-1}},
- {{-7.1933980e-1, 6.9465837e-1}, {3.4899497e-2, -9.9939083e-1}},
- {{-6.1566148e-1, 7.8801075e-1}, {-2.4192190e-1, -9.7029573e-1}},
- {{-5.0000000e-1, 8.6602540e-1}, {-5.0000000e-1, -8.6602540e-1}},
- {{-3.7460659e-1, 9.2718385e-1}, {-7.1933980e-1, -6.9465837e-1}},
- {{-2.4192190e-1, 9.7029573e-1}, {-8.8294759e-1, -4.6947156e-1}},
- {{-1.0452846e-1, 9.9452190e-1}, {-9.7814760e-1, -2.0791169e-1}},
- {{3.4899497e-2, 9.9939083e-1}, {-9.9756405e-1, 6.9756474e-2}},
- {{1.7364818e-1, 9.8480775e-1}, {-9.3969262e-1, 3.4202014e-1}},
- {{3.0901699e-1, 9.5105652e-1}, {-8.0901699e-1, 5.8778525e-1}},
- {{4.3837115e-1, 8.9879405e-1}, {-6.1566148e-1, 7.8801075e-1}},
- {{5.5919290e-1, 8.2903757e-1}, {-3.7460659e-1, 9.2718385e-1}},
- {{6.6913061e-1, 7.4314483e-1}, {-1.0452846e-1, 9.9452190e-1}},
- {{7.6604444e-1, 6.4278761e-1}, {1.7364818e-1, 9.8480775e-1}},
- {{8.4804810e-1, 5.2991926e-1}, {4.3837115e-1, 8.9879405e-1}},
- {{9.1354546e-1, 4.0673664e-1}, {6.6913061e-1, 7.4314483e-1}},
- {{9.6126170e-1, 2.7563736e-1}, {8.4804810e-1, 5.2991926e-1}},
- {{9.9026807e-1, 1.3917310e-1}, {9.6126170e-1, 2.7563736e-1}},
- }};
-
-/**
- * FFT 5 Points template
- * s Sign -1: Forward 1: Inverse
- * x, y Input and output coefficients, of size 5xn
- * n Number of interleaved transform to perform
- */
-static inline void xfft_5(const float s, const struct fft_complex* x,
- struct fft_complex* y, int n) {
- static const float cos1 = 0.3090169944; /* cos(-2Pi 1/5) */
- static const float cos2 = -0.8090169944; /* cos(-2Pi 2/5) */
-
- static const float sin1 = -0.9510565163; /* sin(-2Pi 1/5) */
- static const float sin2 = -0.5877852523; /* sin(-2Pi 2/5) */
-
- for (int i = 0; i < n; i++, x++, y += 5) {
- struct fft_complex s14 = {x[1 * n].re + x[4 * n].re,
- x[1 * n].im + x[4 * n].im};
- struct fft_complex d14 = {x[1 * n].re - x[4 * n].re,
- x[1 * n].im - x[4 * n].im};
-
- struct fft_complex s23 = {x[2 * n].re + x[3 * n].re,
- x[2 * n].im + x[3 * n].im};
- struct fft_complex d23 = {x[2 * n].re - x[3 * n].re,
- x[2 * n].im - x[3 * n].im};
-
- y[0].re = x[0].re + s14.re + s23.re;
- y[0].im = x[0].im + s14.im + s23.im;
-
- y[1].re = x[0].re + s14.re * cos1 + s * d14.im * sin1 + s23.re * cos2 +
- s * d23.im * sin2;
-
- y[1].im = x[0].im + s14.im * cos1 - s * d14.re * sin1 + s23.im * cos2 -
- s * d23.re * sin2;
-
- y[2].re = x[0].re + s14.re * cos2 + s * d14.im * sin2 + s23.re * cos1 -
- s * d23.im * sin1;
-
- y[2].im = x[0].im + s14.im * cos2 - s * d14.re * sin2 + s23.im * cos1 +
- s * d23.re * sin1;
-
- y[3].re = x[0].re + s14.re * cos2 - s * d14.im * sin2 + s23.re * cos1 +
- s * d23.im * sin1;
-
- y[3].im = x[0].im + s14.im * cos2 + s * d14.re * sin2 + s23.im * cos1 -
- s * d23.re * sin1;
-
- y[4].re = x[0].re + s14.re * cos1 - s * d14.im * sin1 + s23.re * cos2 -
- s * d23.im * sin2;
-
- y[4].im = x[0].im + s14.im * cos1 + s * d14.re * sin1 + s23.im * cos2 +
- s * d23.re * sin2;
- }
-}
-
-/**
- * FFT Butterfly 3 Points template
- * s Sign -1: Forward 1: Inverse
- * x, y Input and output coefficients
- * twiddles Twiddles factors, determine size of transform
- * n Number of interleaved transforms
- */
-static inline void xfft_bf3(const float s,
- const struct fft_bf3_twiddles* twiddles,
- const struct fft_complex* x, struct fft_complex* y,
- int n) {
- int n3 = twiddles->n3;
- const struct fft_complex(*w0)[2] = twiddles->t;
- const struct fft_complex(*w1)[2] = w0 + n3, (*w2)[2] = w1 + n3;
-
- const struct fft_complex *x0 = x, *x1 = x0 + n * n3, *x2 = x1 + n * n3;
- struct fft_complex *y0 = y, *y1 = y0 + n3, *y2 = y1 + n3;
-
- for (int i = 0; i < n; i++, y0 += 3 * n3, y1 += 3 * n3, y2 += 3 * n3) {
- for (int j = 0; j < n3; j++, x0++, x1++, x2++) {
- y0[j].re = x0->re + x1->re * w0[j][0].re + s * x1->im * w0[j][0].im +
- x2->re * w0[j][1].re + s * x2->im * w0[j][1].im;
-
- y0[j].im = x0->im + x1->im * w0[j][0].re - s * x1->re * w0[j][0].im +
- x2->im * w0[j][1].re - s * x2->re * w0[j][1].im;
-
- y1[j].re = x0->re + x1->re * w1[j][0].re + s * x1->im * w1[j][0].im +
- x2->re * w1[j][1].re + s * x2->im * w1[j][1].im;
-
- y1[j].im = x0->im + x1->im * w1[j][0].re - s * x1->re * w1[j][0].im +
- x2->im * w1[j][1].re - s * x2->re * w1[j][1].im;
-
- y2[j].re = x0->re + x1->re * w2[j][0].re + s * x1->im * w2[j][0].im +
- x2->re * w2[j][1].re + s * x2->im * w2[j][1].im;
-
- y2[j].im = x0->im + x1->im * w2[j][0].re - s * x1->re * w2[j][0].im +
- x2->im * w2[j][1].re - s * x2->re * w2[j][1].im;
- }
- }
-}
-
-/**
- * FFT Butterfly 2 Points template
- * s Sign -1: Forward 1: Inverse
- * twiddles Twiddles factors, determine size of transform
- * x, y Input and output coefficients
- * n Number of interleaved transforms
- */
-static inline void xfft_bf2(const float s,
- const struct fft_bf2_twiddles* twiddles,
- const struct fft_complex* x, struct fft_complex* y,
- int n) {
- int n2 = twiddles->n2;
- const struct fft_complex* w = twiddles->t;
-
- const struct fft_complex *x0 = x, *x1 = x0 + n * n2;
- struct fft_complex *y0 = y, *y1 = y0 + n2;
-
- for (int i = 0; i < n; i++, y0 += 2 * n2, y1 += 2 * n2) {
- for (int j = 0; j < n2; j++, x0++, x1++) {
- y0[j].re = x0->re + x1->re * w[j].re + s * x1->im * w[j].im;
- y0[j].im = x0->im + x1->im * w[j].re - s * x1->re * w[j].im;
-
- y1[j].re = x0->re - x1->re * w[j].re - s * x1->im * w[j].im;
- y1[j].im = x0->im - x1->im * w[j].re + s * x1->re * w[j].im;
- }
- }
-}
-
-/**
- * Forward FFT 5 Points
- * x, y Input and output coefficients, of size 5xn
- * n Number of interleaved transform to perform
- */
-static void ffft_5(const struct fft_complex* x, struct fft_complex* y, int n) {
- xfft_5(-1, x, y, n);
-}
-
-/**
- * Inverse FFT 5 Points
- * x, y Input and output coefficients, of size 5xn
- * n Number of interleaved transform to perform
- */
-static void ifft_5(const struct fft_complex* x, struct fft_complex* y, int n) {
- xfft_5(1, x, y, n);
-}
-
-/**
- * Forward FFT Butterfly 3 Points
- * twiddles Twiddles factors, determine size of transform
- * x, y Input and output coefficients
- * n Number of interleaved transforms
- */
-static void ffft_bf3(const struct fft_bf3_twiddles* twiddles,
- const struct fft_complex* x, struct fft_complex* y,
- int n) {
- xfft_bf3(-1, twiddles, x, y, n);
-}
-
-/**
- * Inverse FFT Butterfly 3 Points
- * twiddles Twiddles factors, determine size of transform
- * x, y Input and output coefficients
- * n Number of interleaved transforms
- */
-static void ifft_bf3(const struct fft_bf3_twiddles* twiddles,
- const struct fft_complex* x, struct fft_complex* y,
- int n) {
- xfft_bf3(1, twiddles, x, y, n);
-}
-
-/**
- * Forward FFT Butterfly 2 Points
- * twiddles Twiddles factors, determine size of transform
- * x, y Input and output coefficients
- * n Number of interleaved transforms
- */
-static void ffft_bf2(const struct fft_bf2_twiddles* twiddles,
- const struct fft_complex* x, struct fft_complex* y,
- int n) {
- xfft_bf2(-1, twiddles, x, y, n);
-}
-
-/**
- * InverseIFFT Butterfly 2 Points
- * twiddles Twiddles factors, determine size of transform
- * x, y Input and output coefficients
- * n Number of interleaved transforms
- */
-static void ifft_bf2(const struct fft_bf2_twiddles* twiddles,
- const struct fft_complex* x, struct fft_complex* y,
- int n) {
- xfft_bf2(1, twiddles, x, y, n);
-}
-
-/**
- * Perform FFT
- * inverse True on inverse transform else forward
- * x, y0, y1 Input, and 2 scratch buffers of size `n`
- * n Number of points 30, 40, 60, 80, 90, 120, 160, 180, 240
- * return The buffer `y0` or `y1` that hold the result
- *
- * Input `x` can be the same as the `y0` second scratch buffer
- */
-struct fft_complex* fft(bool inverse, const struct fft_complex* x, int n,
- struct fft_complex* y0, struct fft_complex* y1) {
- static const struct fft_bf3_twiddles* twiddles_bf3[] = {&twiddles_15,
- &twiddles_45};
-
- static const struct fft_bf2_twiddles* twiddles_bf2[][3] = {
- {&twiddles_10, &twiddles_30, &twiddles_90},
- {&twiddles_20, &twiddles_60, &twiddles_180},
- {&twiddles_40, &twiddles_120},
- {&twiddles_80, &twiddles_240},
- {&twiddles_160}};
-
- struct fft_complex* y[2] = {y1, y0};
- int i2, i3, is = 0;
-
- /* The number of points `n` can be decomposed as :
- *
- * n = 5^1 * 3^n3 * 2^n2
- *
- * for n = 40, 80, 160 n3 = 0, n2 = [3..5]
- * n = 30, 60, 120, 240 n3 = 1, n2 = [1..4]
- * n = 90, 180 n3 = 2, n2 = [1..2]
- *
- * Note that the expression `n & (n-1) == 0` is equivalent
- * to the check that `n` is a power of 2. */
-
- (inverse ? ifft_5 : ffft_5)(x, y[is], n /= 5);
-
- for (i3 = 0; n & (n - 1); i3++, is ^= 1)
- (inverse ? ifft_bf3 : ffft_bf3)(twiddles_bf3[i3], y[is], y[is ^ 1], n /= 3);
-
- for (i2 = 0; n > 1; i2++, is ^= 1)
- (inverse ? ifft_bf2 : ffft_bf2)(twiddles_bf2[i2][i3], y[is], y[is ^ 1],
- n >>= 1);
-
- return y[is];
-}
diff --git a/system/embdrv/lc3_dec/Common/fft/fft.h b/system/embdrv/lc3_dec/Common/fft/fft.h
deleted file mode 100644
index efc5e11ac9..0000000000
--- a/system/embdrv/lc3_dec/Common/fft/fft.h
+++ /dev/null
@@ -1,52 +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.
- *
- ******************************************************************************/
-
-#ifndef __LC3_OWN_FFT_H
-#define __LC3_OWN_FFT_H
-
-#include <stdbool.h>
-
-/**
- * Complex floating point number
- */
-
-struct fft_complex {
- float re, im;
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Perform FFT
- * inverse True on inverse transform else forward
- * x, y0, y1 Input, and 2 scratch buffers of size `n`
- * n Number of points 30, 40, 60, 80, 90, 120, 160, 180, 240
- * return The buffer `y0` or `y1` that hold the result
- *
- * Input `x` can be the same as the `y0` second scratch buffer
- */
-struct fft_complex* fft(bool inverse, const struct fft_complex* x, int n,
- struct fft_complex* y0, struct fft_complex* y1);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __LC3_OWN_FFT_H */ \ No newline at end of file
diff --git a/system/embdrv/lc3_dec/Decoder/ArithmeticDec.cpp b/system/embdrv/lc3_dec/Decoder/ArithmeticDec.cpp
deleted file mode 100644
index d8ea214899..0000000000
--- a/system/embdrv/lc3_dec/Decoder/ArithmeticDec.cpp
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * ArithmeticDec.cpp
- *
- * 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 "ArithmeticDec.hpp"
-
-#include <algorithm> // std::min
-#include <cmath>
-#include <cstring>
-
-#include "BitReader.hpp"
-#include "SpectralDataTables.hpp"
-#include "TemporalNoiseShapingTables.hpp"
-
-namespace Lc3Dec {
-
-ArithmeticDec::ArithmeticDec(uint16_t NF_, uint16_t NE_, uint16_t rateFlag_,
- uint8_t tns_lpc_weighting_)
- : NF(NF_),
- NE(NE_),
- rateFlag(rateFlag_),
- tns_lpc_weighting(tns_lpc_weighting_),
- X_hat_q_ari(nullptr),
- save_lev(nullptr),
- nf_seed(0),
- nbits_residual(0) {
- X_hat_q_ari = new int16_t[NE];
- save_lev = new uint8_t[NE];
-}
-
-ArithmeticDec::~ArithmeticDec() {
- delete[] X_hat_q_ari;
- delete[] save_lev;
-}
-
-void ac_dec_init(const uint8_t bytes[], uint16_t* bp, struct ac_dec_state* st) {
- st->low = 0;
- st->range = 0x00ffffff;
- for (uint8_t i = 0; i < 3; i++) {
- st->low <<= 8;
- st->low += bytes[(*bp)++];
- }
-}
-
-uint8_t ac_decode(const uint8_t bytes[], uint16_t* bp, struct ac_dec_state* st,
- int16_t cum_freq[], int16_t sym_freq[], uint8_t numsym,
- uint8_t& BEC_detect) {
- uint32_t tmp = st->range >> 10;
- if (st->low >= (tmp << 10)) {
- BEC_detect = 1;
- return 0;
- }
- uint8_t val = numsym - 1;
- while (st->low < tmp * cum_freq[val]) {
- val--;
- }
- st->low -= tmp * cum_freq[val];
- st->range = tmp * sym_freq[val];
- while (st->range < 0x10000) {
- st->low <<= 8;
- st->low &= 0x00ffffff;
- st->low += bytes[(*bp)++];
- st->range <<= 8;
- }
- return val;
-}
-
-double ArithmeticDec::rc_q(uint8_t k, uint8_t f) {
- // with Δ =π/17
- const double pi = std::acos(-1);
- double quantizer_stepsize = pi / 17.0;
- return sin(quantizer_stepsize * (rc_i[k + 8 * f] - 8));
-}
-
-void ArithmeticDec::run(const uint8_t* bytes, uint16_t& bp, uint16_t& bp_side,
- uint8_t& mask_side, int16_t& num_tns_filters,
- int16_t rc_order[], const uint8_t& lsbMode,
- const int16_t& lastnz, uint16_t nbits,
- uint8_t& BEC_detect) {
- int16_t c = 0;
-
- // make local copy of rc_order (is this really what we want)
- rc_order_ari[0] = rc_order[0];
- rc_order_ari[1] = rc_order[1];
-
- /* Arithmetic Decoder Initialization */
- ac_dec_init(bytes, &bp, &st);
-
- /* TNS data */
- // Note: some initialization code like that below can be found in d09r02,
- // but there has been none in d09r01. However, the complete
- // initialization has been added here, in order to get a proper match to
- // the reference output data
- for (uint8_t f = 0; f < 2; f++) {
- for (uint8_t k = 0; k < 8; k++) {
- rc_i[k + 8 * f] = 8;
- }
- }
- for (uint8_t f = 0; f < num_tns_filters; f++) {
- // if (𝑟𝑐𝑜𝑟𝑑𝑒𝑟(𝑓) > 0)
- if (rc_order[f] > 0) {
- //𝑟𝑐𝑜𝑟𝑑𝑒𝑟(𝑓) = ac_decode(bytes, &bp, &st,
- rc_order_ari[f] =
- ac_decode(bytes, &bp, &st, ac_tns_order_cumfreq[tns_lpc_weighting],
- ac_tns_order_freq[tns_lpc_weighting], 8, BEC_detect);
- if (BEC_detect) {
- // early exit to avoid unpredictable side-effects
- return;
- }
-
- rc_order_ari[f] = rc_order_ari[f] + 1;
- // specification (d09r02_F2F) proposes initialization
- // of rc_i at this place; here implemented above in order
- // to be performed independet from num_tns_filters
- for (uint8_t k = 0; k < rc_order_ari[f]; k++) {
- //𝑟𝑐𝑖(𝑘,𝑓) = ac_decode(bytes, &bp, &st, ac_tns_coef_cumfreq[k],
- // rc_i[k][f] = ac_decode(bytes, &bp, &st, ac_tns_coef_cumfreq[k],
- rc_i[k + 8 * f] = ac_decode(bytes, &bp, &st, ac_tns_coef_cumfreq[k],
- ac_tns_coef_freq[k], 17, BEC_detect);
- if (BEC_detect) {
- // early exit to avoid unpredictable side-effects
- return;
- }
- }
- }
- }
-
- /* Spectral data */
- for (uint16_t k = 0; k < lastnz; k += 2) {
- uint16_t t = c + rateFlag;
- // if (k > 𝑁𝐸/2)
- if (k > NE / 2) {
- t += 256;
- }
- //𝑋𝑞̂[k] = 𝑋𝑞̂[k+1] = 0;
- X_hat_q_ari[k] = X_hat_q_ari[k + 1] = 0;
- uint8_t lev;
- uint8_t sym;
- for (lev = 0; lev < 14; lev++) {
- uint8_t pki =
- ac_spec_lookup[t + std::min(lev, static_cast<uint8_t>(3U)) * 1024];
- sym = ac_decode(bytes, &bp, &st, ac_spec_cumfreq[pki], ac_spec_freq[pki],
- 17, BEC_detect);
- if (BEC_detect) {
- // early exit to avoid unpredictable side-effects
- return;
- }
- if (sym < 16) {
- break;
- }
- if (lsbMode == 0 || lev > 0) {
- uint8_t bit = read_bit(bytes, &bp_side, &mask_side);
- //𝑋𝑞̂[k] += bit << lev;
- X_hat_q_ari[k] += bit << lev;
- bit = read_bit(bytes, &bp_side, &mask_side);
- //𝑋𝑞̂[k+1] += bit << lev;
- X_hat_q_ari[k + 1] += bit << lev;
- }
- }
- if (lev == 14) {
- BEC_detect = 1;
- return;
- }
- if (lsbMode == 1) {
- save_lev[k] = lev;
- }
- uint8_t a = sym & 0x3;
- uint8_t b = sym >> 2;
- //𝑋𝑞̂[k] += a << lev;
- //𝑋𝑞̂[k+1] += b << lev;
- // if (𝑋𝑞̂[k] > 0)
- X_hat_q_ari[k] += a << lev;
- X_hat_q_ari[k + 1] += b << lev;
- if (X_hat_q_ari[k] > 0) {
- uint8_t bit = read_bit(bytes, &bp_side, &mask_side);
- if (bit == 1) {
- //𝑋𝑞̂[k] = -𝑋𝑞̂[k];
- X_hat_q_ari[k] = -X_hat_q_ari[k];
- }
- }
- // if (𝑋𝑞̂[k+1] > 0)
- if (X_hat_q_ari[k + 1] > 0) {
- uint8_t bit = read_bit(bytes, &bp_side, &mask_side);
- if (bit == 1) {
- //𝑋𝑞̂[k+1] = -𝑋𝑞̂[k+1];
- X_hat_q_ari[k + 1] = -X_hat_q_ari[k + 1];
- }
- }
- lev = std::min(lev, static_cast<uint8_t>(3));
- if (lev <= 1) {
- t = 1 + (a + b) * (lev + 1);
- } else {
- t = 12 + lev;
- }
- c = (c & 15) * 16 + t;
- // Note: specification of the following line hase been changed from d09r01
- // to d09r02_F2F
- if (bp - bp_side > 3) {
- BEC_detect = 1;
- return;
- }
- }
- // reset remaining fields in array X_hat_q_ari to simplify testing
- for (int16_t k = lastnz; k < NE; k++) {
- X_hat_q_ari[k] = 0;
- }
-
- // 3.4.2.6 Residual data and finalization (d09r02_F2F)
- /* Number of residual bits */
- int16_t nbits_side = nbits - (8 * bp_side + 8 - log2(mask_side));
- int16_t nbits_ari = (bp - 3) * 8;
- nbits_ari += 25 - floor(log2(st.range));
- int16_t nbits_residual_tmp = nbits - (nbits_side + nbits_ari);
- if (nbits_residual_tmp < 0) {
- BEC_detect = 1;
- return;
- }
- nbits_residual = nbits_residual_tmp;
-}
-
-void ArithmeticDec::registerDatapoints(DatapointContainer* datapoints) {
- if (nullptr != datapoints) {
- datapoints->addDatapoint("rateFlag", &rateFlag, sizeof(rateFlag));
- datapoints->addDatapoint("tns_lpc_weighting", &tns_lpc_weighting,
- sizeof(tns_lpc_weighting));
- datapoints->addDatapoint("rc_order_ari", &rc_order_ari[0],
- sizeof(rc_order_ari));
- datapoints->addDatapoint("rc_i", &rc_i[0], sizeof(rc_i));
- datapoints->addDatapoint("X_hat_q_ari", &X_hat_q_ari[0],
- sizeof(int16_t) * NE);
- datapoints->addDatapoint("nbits_residual", &nbits_residual,
- sizeof(nbits_residual));
- }
-}
-
-} // namespace Lc3Dec
diff --git a/system/embdrv/lc3_dec/Decoder/ArithmeticDec.hpp b/system/embdrv/lc3_dec/Decoder/ArithmeticDec.hpp
deleted file mode 100644
index 3e5dd7dfe5..0000000000
--- a/system/embdrv/lc3_dec/Decoder/ArithmeticDec.hpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * ArithmeticDec.hpp
- *
- * 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.
- */
-
-#ifndef __ARITHMETIC_DEC_HPP_
-#define __ARITHMETIC_DEC_HPP_
-
-#include <cstdint>
-
-#include "Datapoints.hpp"
-
-namespace Lc3Dec {
-
-struct ac_dec_state {
- uint32_t low;
- uint32_t range;
-};
-
-class ArithmeticDec {
- public:
- ArithmeticDec(uint16_t NF_, uint16_t NE_, uint16_t rateFlag_,
- uint8_t tns_lpc_weighting_);
- virtual ~ArithmeticDec();
-
- void registerDatapoints(DatapointContainer* datapoints);
-
- double rc_q(uint8_t k, uint8_t f);
-
- void run(const uint8_t* bytes, uint16_t& bp, uint16_t& bp_side,
- uint8_t& mask_side, int16_t& num_tns_filters, int16_t rc_order[],
- const uint8_t& lsbMode, const int16_t& lastnz, uint16_t nbits,
- uint8_t& BEC_detect);
-
- const uint16_t NF;
- const uint16_t NE;
- const uint16_t rateFlag;
- const uint8_t tns_lpc_weighting;
-
- // states & outputs
- int16_t* X_hat_q_ari;
- uint8_t* save_lev;
- int16_t nf_seed;
- int16_t rc_order_ari[2];
- int16_t rc_i[2 * 8]; // [max(rc_order[f])=8][max(num_tns_filters)=2]
- uint16_t nbits_residual;
-
- private:
- struct ac_dec_state st;
-};
-
-} // namespace Lc3Dec
-
-#endif // __ARITHMETIC_DEC_HPP_
diff --git a/system/embdrv/lc3_dec/Decoder/BitReader.cpp b/system/embdrv/lc3_dec/Decoder/BitReader.cpp
deleted file mode 100644
index 161dfb0e5e..0000000000
--- a/system/embdrv/lc3_dec/Decoder/BitReader.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * BitReader.cpp
- *
- * 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 "BitReader.hpp"
-
-namespace Lc3Dec {
-
-uint8_t read_bit(const uint8_t bytes[], uint16_t* bp, uint8_t* mask) {
- uint8_t bit;
- if (bytes[*bp] & *mask) {
- bit = 1;
- } else {
- bit = 0;
- }
- if (*mask == 0x80) {
- *mask = 1;
- *bp -= 1;
- } else {
- *mask <<= 1;
- }
- return bit;
-}
-
-uint16_t read_uint(const uint8_t bytes[], uint16_t* bp, uint8_t* mask,
- uint8_t numbits) {
- uint16_t value = read_bit(bytes, bp, mask);
- for (uint8_t i = 1; i < numbits; i++) {
- uint16_t bit = read_bit(bytes, bp, mask);
- value += bit << i;
- }
- return value;
-}
-
-} // namespace Lc3Dec
diff --git a/system/embdrv/lc3_dec/Decoder/BitReader.hpp b/system/embdrv/lc3_dec/Decoder/BitReader.hpp
deleted file mode 100644
index a6def664c6..0000000000
--- a/system/embdrv/lc3_dec/Decoder/BitReader.hpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * BitReader.hpp
- *
- * 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.
- */
-
-#ifndef __BIT_READER_HPP_
-#define __BIT_READER_HPP_
-
-#include <cstdint>
-
-namespace Lc3Dec {
-
-uint8_t read_bit(const uint8_t bytes[], uint16_t* bp, uint8_t* mask);
-uint16_t read_uint(const uint8_t bytes[], uint16_t* bp, uint8_t* mask,
- uint8_t numbits);
-
-} // namespace Lc3Dec
-
-#endif // __BIT_READER_HPP_
diff --git a/system/embdrv/lc3_dec/Decoder/DecoderFrame.cpp b/system/embdrv/lc3_dec/Decoder/DecoderFrame.cpp
deleted file mode 100644
index 5ce8ff8377..0000000000
--- a/system/embdrv/lc3_dec/Decoder/DecoderFrame.cpp
+++ /dev/null
@@ -1,420 +0,0 @@
-/*
- * DecoderFrame.cpp
- *
- * 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 "DecoderFrame.hpp"
-
-#include <cmath>
-#include <cstring>
-
-#include "BitReader.hpp"
-
-namespace Lc3Dec {
-
-DecoderFrame::DecoderFrame(ResidualSpectrum& residualSpectrum_,
- SpectralNoiseShaping& spectralNoiseShaping_,
- PacketLossConcealment& packetLossConcealment_,
- MdctDec& mdctDec_, const Lc3Config& lc3Config_,
- uint16_t nbytes_)
- : nbytes(nbytes_),
- nbits(nbytes_ * 8),
- lc3Config(lc3Config_),
- tns_lpc_weighting(
- (nbits <
- ((lc3Config.N_ms == Lc3Config::FrameDuration::d10ms) ? 480 : 360))
- ? 1
- : 0),
- sideInformation(lc3Config.NF, lc3Config.NE, lc3Config.Fs_ind),
- arithmeticDec(lc3Config.NF, lc3Config.NE,
- (nbits > (160 + lc3Config.Fs_ind * 160)) ? 512 : 0,
- tns_lpc_weighting),
- residualSpectrum(residualSpectrum_),
- spectralNoiseShaping(spectralNoiseShaping_),
- packetLossConcealment(packetLossConcealment_),
- mdctDec(mdctDec_),
- longTermPostfilter(lc3Config, nbits),
-
- datapoints(nullptr),
-
- frameN(0),
- lastnz(0),
- P_BW(0),
- lsbMode(0),
- gg_ind(0),
- num_tns_filters(0),
- pitch_present(0),
- pitch_index(0),
- ltpf_active(0),
- F_NF(0),
- ind_LF(0),
- ind_HF(0),
- Gind(0),
- LS_indA(0),
- LS_indB(0),
- idxA(0),
- idxB(0),
- nf_seed(0),
- zeroFrame(0),
- gg_off(0),
- X_hat_q_nf(nullptr),
- X_hat_f(nullptr),
- X_s_tns(nullptr),
- X_hat_ss(nullptr),
- x_hat_clip(nullptr) {
- rc_order[0] = 0;
- rc_order[1] = 0;
-
- X_hat_q_nf = new double[lc3Config.NE];
- X_hat_f = new double[lc3Config.NE];
- X_s_tns = new double[lc3Config.NE];
- X_hat_ss = new double[lc3Config.NE];
-}
-
-DecoderFrame::~DecoderFrame() {
- if (nullptr != X_hat_q_nf) {
- delete[] X_hat_q_nf;
- }
- if (nullptr != X_hat_f) {
- delete[] X_hat_f;
- }
- if (nullptr != X_s_tns) {
- delete[] X_s_tns;
- }
- if (nullptr != X_hat_ss) {
- delete[] X_hat_ss;
- }
- if (nullptr != x_hat_clip) {
- delete[] x_hat_clip;
- }
-}
-
-void DecoderFrame::linkPreviousFrame(DecoderFrame* previousFrame) {
- if (nullptr != previousFrame) {
- longTermPostfilter = previousFrame->longTermPostfilter;
- frameN = previousFrame->frameN;
- }
-}
-
-void DecoderFrame::noiseFilling() {
- // 3.4.4 Noise filling (d09r02_F2F)
- // including extensions according to:
- // section 3.4.4. Noise filling (d09r04)
- // Noise filling is performed only when zeroFrame is 0.
- for (int16_t k = 0; k < lc3Config.NE; k++) {
- X_hat_q_nf[k] = residualSpectrum.X_hat_q_residual[k];
- }
- if (0 == zeroFrame) {
- // bandwidth(𝑃𝑏𝑤)
- // NB WB SSWB SWB FB
- //𝑏𝑤_𝑠𝑡𝑜𝑝 80 160 240 320 400
- uint16_t bw_stop_table[5] = {80, 160, 240, 320, 400};
- uint16_t bw_stop = bw_stop_table[P_BW];
- if (lc3Config.N_ms == Lc3Config::FrameDuration::d7p5ms) {
- bw_stop *= 3;
- bw_stop /= 4;
- }
-
- uint16_t NFstart =
- (lc3Config.N_ms == Lc3Config::FrameDuration::d10ms) ? 24 : 18;
- uint16_t NFwidth =
- (lc3Config.N_ms == Lc3Config::FrameDuration::d10ms) ? 3 : 2;
-
- /*
- 𝐿𝑁𝐹 ̂ = (8-𝐹𝑁𝐹)/16;
- for k=0..bw_stop-1
- if 𝐼𝑁𝐹(k)==1
- nf_seed = (13849+nf_seed*31821) & 0xFFFF;
- if nf_seed<0x8000
- 𝑋𝑞 ̂(𝑘) = 𝐿𝑁𝐹 ̂ ;
- else
- 𝑋𝑞 ̂(𝑘) = −𝐿𝑁𝐹 ̂ ;
- */
- uint16_t nf_state = nf_seed;
- double L_NF_hat = (8 - F_NF) / 16.0;
- for (uint16_t k = 0; k < bw_stop; k++) {
- /*
- The indices for the relevant spectral coefficients are given by:
- 𝐼𝑁𝐹 (𝑘) = {
- 1 if 24 ≤ 𝑘 < 𝑏𝑤_𝑠𝑡𝑜𝑝 𝑎𝑛𝑑 𝑋𝑞 ̂(𝑖) == 0 𝑓𝑜𝑟 𝑎𝑙𝑙 𝑖 = 𝑘 − 3. . min(𝑏𝑤𝑠𝑡𝑜𝑝
- − 1, 𝑘 + 3) 0 otherwise # (109) where 𝑏𝑤_𝑠𝑡𝑜𝑝 depends on the bandwidth
- information (see Section 3.4.2.4) as defined in Table 3.17.
- */
- uint8_t I_NF_k = 0;
- if ((NFstart <= k) && (k < bw_stop)) {
- uint16_t limit =
- ((bw_stop - 1) < (k + NFwidth)) ? (bw_stop - 1) : (k + NFwidth);
- I_NF_k = 1;
- for (uint16_t i = k - NFwidth; i <= limit; i++) {
- if (0 != residualSpectrum.X_hat_q_residual[i]) {
- I_NF_k = 0;
- break;
- }
- }
- }
-
- if (1 == I_NF_k) {
- nf_state = (13849 + nf_state * 31821) & 0xFFFF;
- if (nf_state < 0x8000) {
- X_hat_q_nf[k] = L_NF_hat;
- } else {
- X_hat_q_nf[k] = -L_NF_hat;
- }
- }
- }
- }
-}
-
-void DecoderFrame::applyGlobalGain() {
- // 3.4.5 Global gain (d09r02_F2F)
- // The global gain is applied to the spectrum after noise filling has been
- // applied using the following formula (110) & (111)
- int16_t v1 = nbits / (10 * (lc3Config.Fs_ind + 1));
- if (v1 > 115) {
- gg_off = -115;
- } else {
- gg_off = -v1;
- }
- gg_off -= 105;
- gg_off -= 5 * (lc3Config.Fs_ind + 1);
-
- double exponent = (gg_ind + gg_off) / 28.0;
- double gg = pow(10.0, exponent);
- for (int16_t k = 0; k < lc3Config.NE; k++) {
- X_hat_f[k] = gg * X_hat_q_nf[k];
- }
-}
-
-void DecoderFrame::temporalNoiseShaping() {
- // 3.4.6 TNS DecoderFrame (d09r02_F2F)
- /*
- for 𝑘 = 0 to 𝑁𝐸 − 1 do {
- 𝑋𝑠 ̂(𝑛) = 𝑋𝑓 ̂(𝑛)
- }
- s0 = s1 = s2 = s3 = s4 = s5 = s6 = s7 = 0
- for 𝑓 = 0 to num_tns_filters-1 do {
- if (𝑟𝑐𝑜𝑟𝑑𝑒𝑟 (𝑓) > 0)
- {
- for 𝑛 = start_freq(𝑓) to stop_freq(f) − 1 do {
- t = 𝑋𝑓 ̂ (𝑛) − 𝑟𝑐𝑞 (𝑟𝑐𝑜𝑟𝑑𝑒𝑟 (𝑓) − 1 , 𝑓) ∙ 𝑠𝑟𝑐𝑜𝑟𝑑𝑒𝑟(𝑓)−1
- for 𝑘 = 𝑟𝑐𝑜𝑟𝑑𝑒𝑟 (𝑓) − 2 to 0 do {
- 𝑡 = 𝑡 − 𝑟𝑐𝑞 (𝑘, 𝑓) ∙ 𝑠𝑘
- 𝑠𝑘+1 = 𝑟𝑐𝑞 (𝑘, 𝑓) ∙ 𝑡 + 𝑠𝑘
- }
- 𝑋𝑆 ̂(𝑛) = 𝑡
- 𝑠0 = 𝑡
- }
- }
- }
- */
- uint16_t start_freq[2] = {12, 160};
- uint16_t stop_freq[2];
- if (lc3Config.N_ms == Lc3Config::FrameDuration::d10ms) {
- if (4 == P_BW) start_freq[1] = 200;
- switch (P_BW) {
- case 0:
- stop_freq[0] = 80;
- break;
- case 1:
- stop_freq[0] = 160;
- break;
- case 2:
- stop_freq[0] = 240;
- break;
- case 3:
- stop_freq[0] = 160;
- stop_freq[1] = 320;
- break;
- case 4:
- stop_freq[0] = 200;
- stop_freq[1] = 400;
- break;
- }
- } else {
- start_freq[0] = 9;
- if (3 == P_BW) start_freq[1] = 120; // Errata 15098 implemented
- if (4 == P_BW) start_freq[1] = 150;
- switch (P_BW) {
- case 0:
- stop_freq[0] = 60;
- break;
- case 1:
- stop_freq[0] = 120;
- break;
- case 2:
- stop_freq[0] = 180;
- break;
- case 3:
- // stop_freq[0] = 119; // this value is specified in Table 3.19
- // (d09r06_KLG_AY_NH_FhG, 2019-12-20), but gives poor match to 32kHz
- // decoder tests compared to reference decoder
- stop_freq[0] = 120; // this value gives good match to reference decoder
- // and is more consistent to 10ms case
- stop_freq[1] = 240;
- break;
- case 4:
- stop_freq[0] = 150;
- stop_freq[1] = 300;
- break;
- }
- }
-
- for (int16_t k = 0; k < lc3Config.NE; k++) {
- X_s_tns[k] = X_hat_f[k];
- }
- double s[8];
- for (uint8_t k = 0; k < 8; k++) {
- s[k] = 0.0;
- }
- for (uint8_t f = 0; f < num_tns_filters; f++) {
- if (arithmeticDec.rc_order_ari[f] > 0) {
- for (uint16_t n = start_freq[f]; n < stop_freq[f]; n++) {
- double t = X_hat_f[n] -
- arithmeticDec.rc_q(arithmeticDec.rc_order_ari[f] - 1, f) *
- s[arithmeticDec.rc_order_ari[f] - 1];
- for (int8_t k = arithmeticDec.rc_order_ari[f] - 2; k >= 0; k--) {
- t = t - arithmeticDec.rc_q(k, f) * s[k];
- s[k + 1] = arithmeticDec.rc_q(k, f) * t + s[k];
- }
- X_s_tns[n] = t;
- s[0] = t;
- }
- }
- }
-}
-
-void DecoderFrame::runFloat(const uint8_t* bytes, uint8_t BFI,
- uint8_t& BEC_detect) {
- // increment frame counter
- frameN++;
-
- // 5.4.2.2 Initialization
- uint16_t bp = 0;
- uint16_t bp_side = nbytes - 1;
- uint8_t mask_side = 1;
- BEC_detect = BFI; // Note: the base specification initializes BEC_detect with
- // zero, but initialization with BFI is more meaningful
-
- // 5.4.2.3 Side information
- if (!BEC_detect) {
- sideInformation.run(bytes, bp_side, mask_side, P_BW, lastnz, lsbMode,
- gg_ind, num_tns_filters, rc_order, pitch_present,
- pitch_index, ltpf_active, F_NF, ind_LF, ind_HF, Gind,
- LS_indA, LS_indB, idxA, idxB, BEC_detect);
- }
-
- // 3.4.2.4 Bandwidth interpretation (d09r02_F2F)
- // ...included somewhere else?
-
- // 3.4.2.5 Arithmetic decoding (d09r02_F2F)
- if (!BEC_detect) {
- arithmeticDec.run(bytes, bp, bp_side, mask_side, num_tns_filters, rc_order,
- lsbMode, lastnz, nbits, BEC_detect);
- }
-
- if (!BEC_detect) {
- /* Decode residual bits */
- // and 3.4.3 Residual decoding (d09r02_F2F)
- residualSpectrum.run(bytes, bp_side, mask_side, lastnz,
- arithmeticDec.X_hat_q_ari,
- arithmeticDec.nbits_residual, arithmeticDec.save_lev,
- lsbMode, nf_seed, zeroFrame, gg_ind, F_NF);
-
- // 3.4.4 Noise filling (d09r02_F2F)
- noiseFilling();
-
- // 3.4.5 Global gain (d09r02_F2F)
- applyGlobalGain();
-
- // 3.4.6 TNS decoder (d09r02_F2F)
- temporalNoiseShaping();
-
- // 3.4.7 SNS decoder (d09r02_F2F)
- spectralNoiseShaping.run(
- X_s_tns, X_hat_ss, ind_LF, ind_HF, sideInformation.submodeMSB,
- sideInformation.submodeLSB, Gind, LS_indA, LS_indB, idxA, idxB);
- }
-
- // Appendix B. Packet Loss Concealment (d09r02_F2F)
- packetLossConcealment.run(BEC_detect, X_hat_ss, ltpf_active);
-
- // 3.4.8 Low delay MDCT synthesis (d09r02_F2F)
- mdctDec.run(X_hat_ss);
-
- // 3.4.9 Long Term Postfilter (d09r02_F2F)
- if (0 == pitch_present) {
- pitch_index = 0;
- ltpf_active = 0;
- }
- longTermPostfilter.setInputX(mdctDec.x_hat_mdct);
- longTermPostfilter.run(ltpf_active, pitch_index);
-}
-
-void DecoderFrame::registerDatapoints(DatapointContainer* datapoints_) {
- datapoints = datapoints_;
- if (nullptr != datapoints) {
- datapoints->addDatapoint("fs_idx", &lc3Config.Fs_ind,
- sizeof(lc3Config.Fs_ind));
-
- datapoints->addDatapoint("frameN", &frameN, sizeof(frameN));
-
- datapoints->addDatapoint("lastnz", &lastnz, sizeof(lastnz));
- datapoints->addDatapoint("P_BW", &P_BW, sizeof(P_BW));
- datapoints->addDatapoint("lsbMode", &lsbMode, sizeof(lsbMode));
- datapoints->addDatapoint("gg_ind", &gg_ind, sizeof(gg_ind));
- datapoints->addDatapoint("num_tns_filters", &num_tns_filters,
- sizeof(num_tns_filters));
- datapoints->addDatapoint("rc_order", &rc_order[0], sizeof(rc_order));
- datapoints->addDatapoint("pitch_index", &pitch_index, sizeof(pitch_index));
- datapoints->addDatapoint("pitch_present", &pitch_present,
- sizeof(pitch_present));
- datapoints->addDatapoint("ltpf_active", &ltpf_active, sizeof(ltpf_active));
- datapoints->addDatapoint("F_NF", &F_NF, sizeof(F_NF));
- datapoints->addDatapoint("ind_LF", &ind_LF, sizeof(ind_LF));
- datapoints->addDatapoint("ind_HF", &ind_HF, sizeof(ind_HF));
- datapoints->addDatapoint("Gind", &Gind, sizeof(Gind));
- datapoints->addDatapoint("LS_indA", &LS_indA, sizeof(LS_indA));
- datapoints->addDatapoint("idxA", &idxA, sizeof(idxA));
- datapoints->addDatapoint("idxB", &idxB, sizeof(idxB));
-
- datapoints->addDatapoint("nf_seed", &nf_seed, sizeof(nf_seed));
- datapoints->addDatapoint("zeroFrame", &zeroFrame, sizeof(zeroFrame));
-
- datapoints->addDatapoint("gg_off", &gg_off, sizeof(gg_off));
- datapoints->addDatapoint("rc_i_tns", &arithmeticDec.rc_i[0],
- sizeof(arithmeticDec.rc_i[0]) * 8);
-
- datapoints->addDatapoint("X_hat_q_nf", &X_hat_q_nf[0],
- sizeof(double) * lc3Config.NE);
- datapoints->addDatapoint("X_s_tns", &X_s_tns[0],
- sizeof(double) * lc3Config.NE);
- datapoints->addDatapoint("X_hat_ss", &X_hat_ss[0],
- sizeof(double) * lc3Config.NE);
-
- if (nullptr == x_hat_clip) {
- x_hat_clip = new double[lc3Config.NF];
- }
- datapoints->addDatapoint("x_hat_clip", &x_hat_clip[0],
- sizeof(double) * lc3Config.NF);
-
- sideInformation.registerDatapoints(datapoints);
- arithmeticDec.registerDatapoints(datapoints);
- longTermPostfilter.registerDatapoints(datapoints);
- }
-}
-
-} // namespace Lc3Dec
diff --git a/system/embdrv/lc3_dec/Decoder/DecoderFrame.hpp b/system/embdrv/lc3_dec/Decoder/DecoderFrame.hpp
deleted file mode 100644
index 4ce1c86b66..0000000000
--- a/system/embdrv/lc3_dec/Decoder/DecoderFrame.hpp
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * DecoderFrame.hpp
- *
- * 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.
- */
-
-#ifndef __DECODER_FRAME_HPP_
-#define __DECODER_FRAME_HPP_
-
-#include <cstdint>
-
-#include "ArithmeticDec.hpp"
-#include "Datapoints.hpp"
-#include "Lc3Config.hpp"
-#include "LongTermPostfilter.hpp"
-#include "MdctDec.hpp"
-#include "PacketLossConcealment.hpp"
-#include "ResidualSpectrum.hpp"
-#include "SideInformation.hpp"
-#include "SpectralNoiseShaping.hpp"
-
-namespace Lc3Dec {
-
-class DecoderFrame {
- public:
- DecoderFrame(ResidualSpectrum& residualSpectrum_,
- SpectralNoiseShaping& spectralNoiseShaping_,
- PacketLossConcealment& packetLossConcealment_, MdctDec& mdctDec_,
- const Lc3Config& lc3Config_, uint16_t nbytes_);
- virtual ~DecoderFrame();
-
- void registerDatapoints(DatapointContainer* datapoints_);
-
- template <typename T>
- void run(const uint8_t* bytes, uint8_t BFI,
- uint16_t bits_per_audio_sample_dec, T* x_out, uint8_t& BEC_detect) {
- if (!lc3Config.isValid()) {
- return;
- }
-
- // main decoder implementation: 3.4.1 until 3.4.9 (d09r06)
- runFloat(bytes, BFI, BEC_detect);
-
- // 3.4.10 Output signal scaling and rounding (d09r06)
- const uint32_t outputScale = 1UL << (-15 + bits_per_audio_sample_dec - 1);
- for (uint16_t k = 0; k < lc3Config.NF; k++) {
- double x_hat_clip_local;
- if (longTermPostfilter.x_hat_ltpf[k] > 32767) {
- x_hat_clip_local = 32767;
- } else if (longTermPostfilter.x_hat_ltpf[k] < -32768) {
- x_hat_clip_local = -32768;
- } else {
- x_hat_clip_local = longTermPostfilter.x_hat_ltpf[k];
- }
-
- // datapoint buffer for x_hat_clip only prepared when datapoints are
- // available
- if (nullptr != x_hat_clip) {
- x_hat_clip[k] = x_hat_clip_local;
- }
-
- // Round 𝑥 to nearest integer, e.g., ⌊−4.5⌉ = −5, ⌊−3.2⌉ = −3, ⌊3.2⌉ = 3,
- // ⌊4.5⌉ = 5,
- if (x_hat_clip_local > 0) {
- x_out[k] = outputScale * x_hat_clip_local + 0.5;
- } else {
- x_out[k] = outputScale * x_hat_clip_local - 0.5;
- }
- }
-
- if (nullptr != datapoints) {
- datapoints->log("x_out", &x_out[0], sizeof(T) * lc3Config.NF);
- datapoints->log("BER_detect", &BEC_detect, sizeof(BEC_detect));
- }
- }
-
- void linkPreviousFrame(DecoderFrame* previousFrame);
-
- // per instance constant parameter
- const uint16_t nbytes;
- const uint16_t nbits;
- const Lc3Config& lc3Config;
- const uint8_t tns_lpc_weighting;
-
- private:
- void runFloat(const uint8_t* bytes, uint8_t BFI, uint8_t& BEC_detect);
-
- void noiseFilling();
- void applyGlobalGain();
- void temporalNoiseShaping();
-
- SideInformation sideInformation;
- ArithmeticDec arithmeticDec;
- ResidualSpectrum& residualSpectrum;
- SpectralNoiseShaping& spectralNoiseShaping;
- PacketLossConcealment& packetLossConcealment;
- MdctDec& mdctDec;
- LongTermPostfilter longTermPostfilter;
-
- DatapointContainer* datapoints;
-
- // states & outputs
- int16_t frameN;
-
- int16_t lastnz;
- int16_t P_BW;
- uint8_t lsbMode;
- int16_t gg_ind;
- int16_t num_tns_filters;
- int16_t rc_order[2];
- uint8_t pitch_present;
- int16_t pitch_index;
- int16_t ltpf_active;
- int16_t F_NF;
- int16_t ind_LF;
- int16_t ind_HF;
- int16_t Gind;
- int16_t LS_indA;
- int16_t LS_indB;
- int32_t idxA;
- int16_t idxB;
- uint16_t nf_seed;
- uint16_t zeroFrame;
- int16_t gg_off;
- double* X_hat_q_nf;
- double* X_hat_f;
- double* X_s_tns;
- double* X_hat_ss;
- double* x_hat_clip;
-};
-
-} // namespace Lc3Dec
-
-#endif // __DECODER_FRAME_HPP_
diff --git a/system/embdrv/lc3_dec/Decoder/DecoderTop.cpp b/system/embdrv/lc3_dec/Decoder/DecoderTop.cpp
deleted file mode 100644
index 5b7f6acb36..0000000000
--- a/system/embdrv/lc3_dec/Decoder/DecoderTop.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * DecoderTop.cpp
- *
- * 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 "DecoderTop.hpp"
-
-namespace Lc3Dec {
-
-DecoderTop::DecoderTop(uint16_t fs_, DatapointContainer* datapoints_)
- : DecoderTop(Lc3Config(fs_, Lc3Config::FrameDuration::d10ms, 1),
- datapoints_) {}
-
-DecoderTop::DecoderTop(Lc3Config lc3Config_, DatapointContainer* datapoints_)
- : lc3Config(lc3Config_),
- datapoints(datapoints_),
- decoderCurrentFrame(nullptr),
- decoderPreviousFrame(nullptr),
- residualSpectrum(lc3Config_.NE),
- spectralNoiseShaping(lc3Config),
- packetLossConcealment(lc3Config_.NE),
- mdctDec(lc3Config) {
- if (nullptr != datapoints) {
- residualSpectrum.registerDatapoints(datapoints);
- spectralNoiseShaping.registerDatapoints(datapoints);
- packetLossConcealment.registerDatapoints(datapoints);
- mdctDec.registerDatapoints(datapoints);
- }
-}
-
-DecoderTop::~DecoderTop() {
- if (nullptr != decoderPreviousFrame) {
- delete decoderPreviousFrame;
- }
- if (nullptr != decoderCurrentFrame) {
- delete decoderCurrentFrame;
- }
-}
-
-} // namespace Lc3Dec
diff --git a/system/embdrv/lc3_dec/Decoder/DecoderTop.hpp b/system/embdrv/lc3_dec/Decoder/DecoderTop.hpp
deleted file mode 100644
index 268a574621..0000000000
--- a/system/embdrv/lc3_dec/Decoder/DecoderTop.hpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * DecoderTop.hpp
- *
- * 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.
- */
-
-#ifndef __DECODER_TOP_HPP_
-#define __DECODER_TOP_HPP_
-
-#include <cstdint>
-
-#include "Datapoints.hpp"
-#include "DecoderFrame.hpp"
-#include "Lc3Config.hpp"
-#include "MdctDec.hpp"
-#include "PacketLossConcealment.hpp"
-#include "ResidualSpectrum.hpp"
-#include "SpectralNoiseShaping.hpp"
-
-namespace Lc3Dec {
-
-class DecoderTop {
- public:
- DecoderTop(uint16_t fs_, DatapointContainer* datapoints_ = nullptr);
- DecoderTop(Lc3Config lc3Config_, DatapointContainer* datapoints_ = nullptr);
- virtual ~DecoderTop();
-
- template <typename T>
- void run(const uint8_t* bytes, uint16_t nbytes, uint8_t BFI,
- uint8_t bits_per_audio_sample_dec, T* x_out, uint8_t& BEC_detect) {
- if ((nullptr == decoderCurrentFrame) ||
- (decoderCurrentFrame->nbytes != nbytes)) {
- // We need to instantiate a new DecoderFrame only
- // when byte_count has been changed. Thus, frequent
- // dynamic memory allocation can be constrained to
- // rate optimized operation.
- if (nullptr != decoderPreviousFrame) {
- delete decoderPreviousFrame;
- }
- decoderPreviousFrame = decoderCurrentFrame;
- decoderCurrentFrame =
- new DecoderFrame(residualSpectrum, spectralNoiseShaping,
- packetLossConcealment, mdctDec, lc3Config, nbytes);
- decoderCurrentFrame->linkPreviousFrame(decoderPreviousFrame);
- if (nullptr != datapoints) {
- // Another way to make to call optional would be to split run() into
- // init(), registerDatapoints() & remaining run() -> we preferred the
- // simpler
- // API and thus designed this registration being dependent on the
- // availability of datapoints.
- decoderCurrentFrame->registerDatapoints(datapoints);
- }
- }
- decoderCurrentFrame->run<T>(bytes, BFI, bits_per_audio_sample_dec, x_out,
- BEC_detect);
- }
-
- const Lc3Config lc3Config;
-
- private:
- DatapointContainer* datapoints;
- DecoderFrame* decoderCurrentFrame;
- DecoderFrame* decoderPreviousFrame;
- ResidualSpectrum residualSpectrum;
- SpectralNoiseShaping spectralNoiseShaping;
- PacketLossConcealment packetLossConcealment;
- MdctDec mdctDec;
-};
-
-} // namespace Lc3Dec
-
-#endif // __DECODER_TOP_HPP_
diff --git a/system/embdrv/lc3_dec/Decoder/Lc3Decoder.cpp b/system/embdrv/lc3_dec/Decoder/Lc3Decoder.cpp
deleted file mode 100644
index ccc7cf4fbc..0000000000
--- a/system/embdrv/lc3_dec/Decoder/Lc3Decoder.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Lc3Decoder.cpp
- *
- * 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 "Lc3Decoder.hpp"
-
-#include <cstring>
-
-#include "DecoderTop.hpp"
-
-using namespace Lc3Dec;
-
-Lc3Decoder::Lc3Decoder(uint16_t Fs, Lc3Config::FrameDuration frameDuration)
- : Lc3Decoder(Lc3Config(Fs, frameDuration, 1)) {}
-
-Lc3Decoder::Lc3Decoder(Lc3Config lc3Config_, uint8_t bits_per_audio_sample_dec_,
- uint16_t byte_count_max_dec_, void* datapoints)
- : lc3Config(lc3Config_),
- bits_per_audio_sample_dec(bits_per_audio_sample_dec_),
- byte_count_max_dec((byte_count_max_dec_ < 400) ? byte_count_max_dec_
- : 400),
- decoderList(lc3Config.Nc) {
- // proceed only with valid configuration
- if (lc3Config.isValid()) {
- for (uint8_t channelNr = 0; channelNr < lc3Config.Nc; channelNr++) {
- decoderList[channelNr] = new DecoderTop(
- lc3Config, reinterpret_cast<DatapointContainer*>(datapoints));
- }
- }
-}
-
-Lc3Decoder::~Lc3Decoder() {
- for (uint8_t channelNr = 0; channelNr < lc3Config.Nc; channelNr++) {
- DecoderTop* decoderTop = decoderList[channelNr];
- if (nullptr != decoderTop) {
- delete decoderTop;
- }
- }
-}
-
-uint8_t Lc3Decoder::run(const uint8_t* bytes, uint16_t byte_count, uint8_t BFI,
- int16_t* x_out, uint16_t x_out_size,
- uint8_t& BEC_detect, uint8_t channelNr) {
- if (!lc3Config.isValid()) {
- return INVALID_CONFIGURATION;
- }
- if ((byte_count < 20) || (byte_count > byte_count_max_dec)) {
- return INVALID_BYTE_COUNT;
- }
- if (lc3Config.NF != x_out_size) {
- return INVALID_X_OUT_SIZE;
- }
- if (bits_per_audio_sample_dec != 16) {
- return INVALID_BITS_PER_AUDIO_SAMPLE;
- }
- if (nullptr == decoderList[channelNr]) {
- return DECODER_ALLOCATION_ERROR;
- }
-
- decoderList[channelNr]->run<int16_t>(
- bytes, byte_count, BFI, bits_per_audio_sample_dec, x_out, BEC_detect);
- return ERROR_FREE;
-}
-
-uint8_t Lc3Decoder::run(const uint8_t* bytes, uint16_t byte_count, uint8_t BFI,
- int32_t* x_out, uint16_t x_out_size,
- uint8_t& BEC_detect, uint8_t channelNr) {
- if (!lc3Config.isValid()) {
- return INVALID_CONFIGURATION;
- }
- if ((byte_count < 20) || (byte_count > byte_count_max_dec)) {
- return INVALID_BYTE_COUNT;
- }
- if (lc3Config.NF != x_out_size) {
- return INVALID_X_OUT_SIZE;
- }
- if ((bits_per_audio_sample_dec != 16) && (bits_per_audio_sample_dec != 24) &&
- (bits_per_audio_sample_dec != 32)) {
- return INVALID_BITS_PER_AUDIO_SAMPLE;
- }
- if (nullptr == decoderList[channelNr]) {
- return DECODER_ALLOCATION_ERROR;
- }
-
- decoderList[channelNr]->run<int32_t>(
- bytes, byte_count, BFI, bits_per_audio_sample_dec, x_out, BEC_detect);
- return ERROR_FREE;
-}
-
-uint8_t Lc3Decoder::run(const uint8_t* bytes,
- const uint16_t* byte_count_per_channel,
- const uint8_t* BFI_per_channel, int16_t* x_out,
- uint32_t x_out_size, uint8_t* BEC_detect_per_channel) {
- if (!lc3Config.isValid()) {
- return INVALID_CONFIGURATION;
- }
- if (lc3Config.NF * lc3Config.Nc != x_out_size) {
- return INVALID_X_OUT_SIZE;
- }
-
- uint8_t returnCode = ERROR_FREE;
- uint32_t byteOffset = 0;
- for (uint8_t channelNr = 0; channelNr < lc3Config.Nc; channelNr++) {
- // Note: bitwise or of the single channel return code will not allow
- // uniquely to decode
- // the given error. The idea is to catch any error. This decision
- // makes the API more simple. However, when the precise error code is
- // needed, the single channel call has to be made separately.
- returnCode |=
- run(&bytes[byteOffset], byte_count_per_channel[channelNr],
- BFI_per_channel[channelNr], &x_out[channelNr * lc3Config.NF],
- lc3Config.NF, BEC_detect_per_channel[channelNr], channelNr);
- byteOffset += byte_count_per_channel[channelNr];
- }
- return returnCode;
-}
-
-uint8_t Lc3Decoder::run(const uint8_t* bytes,
- const uint16_t* byte_count_per_channel,
- const uint8_t* BFI_per_channel, int32_t* x_out,
- uint32_t x_out_size, uint8_t* BEC_detect_per_channel) {
- if (!lc3Config.isValid()) {
- return INVALID_CONFIGURATION;
- }
- if (lc3Config.NF * lc3Config.Nc != x_out_size) {
- return INVALID_X_OUT_SIZE;
- }
-
- uint8_t returnCode = ERROR_FREE;
- uint32_t byteOffset = 0;
- for (uint8_t channelNr = 0; channelNr < lc3Config.Nc; channelNr++) {
- // Note: bitwise or of the single channel return code will not allow
- // uniquely to decode
- // the given error. The idea is to catch any error. This decision
- // makes the API more simple. However, when the precise error code is
- // needed, the single channel call has to be made separately.
- returnCode |=
- run(&bytes[byteOffset], byte_count_per_channel[channelNr],
- BFI_per_channel[channelNr], &x_out[channelNr * lc3Config.NF],
- lc3Config.NF, BEC_detect_per_channel[channelNr], channelNr);
- byteOffset += byte_count_per_channel[channelNr];
- }
- return returnCode;
-}
diff --git a/system/embdrv/lc3_dec/Decoder/LongTermPostfilter.cpp b/system/embdrv/lc3_dec/Decoder/LongTermPostfilter.cpp
deleted file mode 100644
index 3838c7f7e7..0000000000
--- a/system/embdrv/lc3_dec/Decoder/LongTermPostfilter.cpp
+++ /dev/null
@@ -1,472 +0,0 @@
-/*
- * LongTermPostfilter.cpp
- *
- * 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 "LongTermPostfilter.hpp"
-
-#include <cmath>
-
-#include "LongTermPostfilterCoefficients.hpp"
-
-namespace Lc3Dec {
-
-LongTermPostfilter::LongTermPostfilter(const Lc3Config& lc3Config_,
- uint16_t nbits)
- : lc3Config(lc3Config_),
- numMemBlocks((lc3Config.N_ms == Lc3Config::FrameDuration::d10ms) ? 2 : 3),
- x_hat_ltpf(nullptr),
- ltpf_active_prev(0),
- blockStartIndex(0),
- c_num(nullptr),
- c_den(nullptr),
- c_num_mem(nullptr),
- c_den_mem(nullptr),
- x_hat_ltpfin(nullptr),
- x_hat_mem(nullptr),
- x_hat_ltpf_mem(nullptr),
- p_int(0),
- p_fr(0),
- p_int_mem(0),
- p_fr_mem(0) {
- x_hat_ltpfin = new double[lc3Config.NF];
- x_hat_mem = new double[lc3Config.NF * numMemBlocks];
- x_hat_ltpf = new double[lc3Config.NF];
- x_hat_ltpf_mem = new double[lc3Config.NF * numMemBlocks];
-
- for (uint16_t n = 0; n < lc3Config.NF * numMemBlocks; n++) {
- x_hat_mem[n] = 0.0;
- x_hat_ltpf_mem[n] = 0.0;
- }
-
- setGainParams(nbits);
-
- L_den = ceil(lc3Config.Fs / 4000.0);
- if (L_den < 4) L_den = 4;
- L_num = L_den - 2;
-
- c_num = new double[L_num + 1];
- c_den = new double[L_den + 1];
- c_num_mem = new double[L_num + 1];
- c_den_mem = new double[L_den + 1];
-}
-
-LongTermPostfilter::~LongTermPostfilter() {
- if (nullptr != x_hat_ltpfin) {
- delete[] x_hat_ltpfin;
- }
- if (nullptr != x_hat_mem) {
- delete[] x_hat_mem;
- }
- if (nullptr != x_hat_ltpf) {
- delete[] x_hat_ltpf;
- }
- if (nullptr != x_hat_ltpf_mem) {
- delete[] x_hat_ltpf_mem;
- }
- if (nullptr != c_num) {
- delete[] c_num;
- }
- if (nullptr != c_den) {
- delete[] c_den;
- }
- if (nullptr != c_num_mem) {
- delete[] c_num_mem;
- }
- if (nullptr != c_den_mem) {
- delete[] c_den_mem;
- }
-}
-
-LongTermPostfilter& LongTermPostfilter::operator=(
- const LongTermPostfilter& src) {
- // TODO we should assert, that NF is equal in src and *this!
-
- ltpf_active_prev = src.ltpf_active_prev;
- blockStartIndex = src.blockStartIndex;
- p_int = src.p_int;
- p_fr = src.p_fr;
- p_int_mem = src.p_int_mem;
- p_fr_mem = src.p_fr_mem;
-
- for (uint16_t k = 0; k < lc3Config.NF; k++) {
- x_hat_ltpfin[k] = src.x_hat_ltpfin[k];
- x_hat_mem[k] = src.x_hat_mem[k];
- x_hat_mem[k + lc3Config.NF] = src.x_hat_mem[k + lc3Config.NF];
- if (numMemBlocks > 2) {
- x_hat_mem[k + lc3Config.NF * 2] = src.x_hat_mem[k + lc3Config.NF * 2];
- }
- x_hat_ltpf[k] = src.x_hat_ltpf[k];
- x_hat_ltpf_mem[k] = src.x_hat_ltpf_mem[k];
- x_hat_ltpf_mem[k + lc3Config.NF] = src.x_hat_ltpf_mem[k + lc3Config.NF];
- if (numMemBlocks > 2) {
- x_hat_ltpf_mem[k + lc3Config.NF * 2] =
- src.x_hat_ltpf_mem[k + lc3Config.NF * 2];
- }
- }
- for (uint8_t k = 0; k < L_num + 1; k++) {
- c_num[k] = src.c_num[k];
- c_num_mem[k] = src.c_num_mem[k];
- }
- for (uint8_t k = 0; k < L_den + 1; k++) {
- c_den[k] = src.c_den[k];
- c_den_mem[k] = src.c_den_mem[k];
- }
-
- return *this;
-}
-
-void LongTermPostfilter::setGainParams(uint16_t nbits) {
- uint16_t t_nbits = (lc3Config.N_ms == Lc3Config::FrameDuration::d7p5ms)
- ? round(nbits * 10 / 7.5)
- : nbits;
-
- if (t_nbits < 320 + lc3Config.Fs_ind * 80) {
- gain_ltpf = 0.4;
- gain_ind = 0;
- } else if (t_nbits < 400 + lc3Config.Fs_ind * 80) {
- gain_ltpf = 0.35;
- gain_ind = 1;
- } else if (t_nbits < 480 + lc3Config.Fs_ind * 80) {
- gain_ltpf = 0.3;
- gain_ind = 2;
- } else if (t_nbits < 560 + lc3Config.Fs_ind * 80) {
- gain_ltpf = 0.25;
- gain_ind = 3;
- } else {
- gain_ltpf = 0;
- gain_ind = 4; // just a guess so far!
- }
-}
-
-void LongTermPostfilter::computeFilterCoeffs(uint16_t pitch_index) {
- uint16_t pitch_int;
- double pitch_fr;
- if (pitch_index >= 440) {
- pitch_int = pitch_index - 283;
- pitch_fr = 0.0;
- } else if (pitch_index >= 380) {
- pitch_int = pitch_index / 2 - 63;
- pitch_fr = 2 * pitch_index - 4 * pitch_int - 252;
- } else {
- pitch_int = pitch_index / 4 + 32;
- pitch_fr = pitch_index - 4 * pitch_int + 128;
- }
- double pitch = pitch_int + pitch_fr / 4;
-
- double pitch_fs = pitch * (8000 * ceil(lc3Config.Fs / 8000.0) / 12800.0);
- uint16_t p_up = (pitch_fs * 4) + 0.5;
-
- // update index parameters for current frame
- p_int = p_up / 4;
- p_fr = p_up - 4 * p_int;
-
- double* tab_ltpf_num_fs =
- tab_ltpf_num_8000[gain_ind]; // default to avoid warnings
- double* tab_ltpf_den_fs =
- tab_ltpf_den_8000[p_fr]; // default to avoid warnings
- switch (lc3Config.Fs) {
- case 8000:
- tab_ltpf_num_fs = tab_ltpf_num_8000[gain_ind];
- tab_ltpf_den_fs = tab_ltpf_den_8000[p_fr];
- break;
- case 16000:
- tab_ltpf_num_fs = tab_ltpf_num_16000[gain_ind];
- tab_ltpf_den_fs = tab_ltpf_den_16000[p_fr];
- break;
- case 24000:
- tab_ltpf_num_fs = tab_ltpf_num_24000[gain_ind];
- tab_ltpf_den_fs = tab_ltpf_den_24000[p_fr];
- break;
- case 32000:
- tab_ltpf_num_fs = tab_ltpf_num_32000[gain_ind];
- tab_ltpf_den_fs = tab_ltpf_den_32000[p_fr];
- break;
- case 44100:
- case 48000:
- tab_ltpf_num_fs = tab_ltpf_num_48000[gain_ind];
- tab_ltpf_den_fs = tab_ltpf_den_48000[p_fr];
- break;
- }
-
- for (uint8_t k = 0; k <= L_num; k++) {
- c_num[k] = 0.85 * gain_ltpf * tab_ltpf_num_fs[k];
- }
- for (uint8_t k = 0; k <= L_den; k++) {
- c_den[k] = gain_ltpf * tab_ltpf_den_fs[k];
- }
-}
-
-void LongTermPostfilter::setInputX(const double* const x_hat) {
- for (uint16_t n = 0; n < lc3Config.NF; n++) {
- x_hat_ltpfin[n] = x_hat[n];
- }
-}
-
-void LongTermPostfilter::run(int16_t ltpf_active, int16_t pitch_index) {
- // further register updates (maybe move to explicit registerUpdate method)
- p_int_mem = p_int;
- p_fr_mem = p_fr;
- for (uint8_t k = 0; k <= L_num; k++) {
- c_num_mem[k] = c_num[k];
- }
- for (uint8_t k = 0; k <= L_den; k++) {
- c_den_mem[k] = c_den[k];
- }
-
- // compute new coefficients
- if (1 == ltpf_active) {
- computeFilterCoeffs(pitch_index);
- } else {
- p_int = 0;
- p_fr = 0;
- for (uint8_t k = 0; k <= L_num; k++) {
- c_num[k] = 0;
- }
- for (uint8_t k = 0; k <= L_den; k++) {
- c_den[k] = 0;
- }
- }
-
- // start processing of input signal
- for (uint16_t n = 0; n < lc3Config.NF; n++) {
- x_hat_mem[blockStartIndex + n] = x_hat_ltpfin[n];
- }
- double norm = (lc3Config.N_ms == Lc3Config::FrameDuration::d10ms)
- ? lc3Config.NF / 4
- : lc3Config.NF / 3;
- uint16_t sample2p5ms =
- (lc3Config.Fs == 44100) ? 48000 / 400 : lc3Config.Fs / 400;
-
- if ((0 == ltpf_active) && (0 == ltpf_active_prev)) {
- //*** transition case 1 **********************************************
- for (uint16_t n = 0; n < lc3Config.NF; n++) {
- x_hat_ltpf_mem[blockStartIndex + n] = x_hat_mem[blockStartIndex + n];
- }
- } else if ((1 == ltpf_active) && (0 == ltpf_active_prev)) {
- //*** transition case 2 **********************************************
- for (uint16_t n = 0; n < sample2p5ms; n++) {
- x_hat_ltpf_mem[blockStartIndex + n] = x_hat_mem[blockStartIndex + n];
- double filtOut = 0.0;
- for (uint16_t k = 0; k <= L_num; k++) {
- int16_t x_hat_index = blockStartIndex + n - k;
- if (x_hat_index < 0) {
- x_hat_index += numMemBlocks * lc3Config.NF;
- }
- filtOut += c_num[k] * x_hat_mem[x_hat_index];
- }
- for (uint16_t k = 0; k <= L_den; k++) {
- int16_t x_hat_ltpf_index = blockStartIndex + n - p_int + L_den / 2 - k;
- if (x_hat_ltpf_index < 0) {
- x_hat_ltpf_index += numMemBlocks * lc3Config.NF;
- }
- filtOut -= c_den[k] * x_hat_ltpf_mem[x_hat_ltpf_index];
- }
- filtOut *= n / norm;
- x_hat_ltpf_mem[blockStartIndex + n] -= filtOut;
- }
-
- for (uint16_t n = sample2p5ms; n < lc3Config.NF; n++) {
- x_hat_ltpf_mem[blockStartIndex + n] = x_hat_mem[blockStartIndex + n];
- double filtOut = 0.0;
- for (uint16_t k = 0; k <= L_num; k++) {
- int16_t x_hat_index = blockStartIndex + n - k;
- if (x_hat_index < 0) {
- x_hat_index += numMemBlocks * lc3Config.NF;
- }
- filtOut += c_num[k] * x_hat_mem[x_hat_index];
- }
- for (uint16_t k = 0; k <= L_den; k++) {
- int16_t x_hat_ltpf_index =
- blockStartIndex + n - p_int + L_den / 2.0 - k;
- if (x_hat_ltpf_index < 0) {
- x_hat_ltpf_index += numMemBlocks * lc3Config.NF;
- }
- filtOut -= c_den[k] * x_hat_ltpf_mem[x_hat_ltpf_index];
- }
- x_hat_ltpf_mem[blockStartIndex + n] -= filtOut;
- }
-
- } else if ((0 == ltpf_active) && (1 == ltpf_active_prev)) {
- //*** transition case 3 **********************************************
- for (uint16_t n = 0; n < sample2p5ms; n++) {
- x_hat_ltpf_mem[blockStartIndex + n] = x_hat_mem[blockStartIndex + n];
- double filtOut = 0.0;
- for (uint16_t k = 0; k <= L_num; k++) {
- int16_t x_hat_index = blockStartIndex + n - k;
- if (x_hat_index < 0) {
- x_hat_index += numMemBlocks * lc3Config.NF;
- }
- filtOut += c_num_mem[k] * x_hat_mem[x_hat_index];
- }
- for (uint16_t k = 0; k <= L_den; k++) {
- int16_t x_hat_ltpf_index =
- blockStartIndex + n - p_int_mem + L_den / 2 - k;
- if (x_hat_ltpf_index < 0) {
- x_hat_ltpf_index += numMemBlocks * lc3Config.NF;
- }
- filtOut -= c_den_mem[k] * x_hat_ltpf_mem[x_hat_ltpf_index];
- }
- filtOut *= 1 - (n / norm);
- x_hat_ltpf_mem[blockStartIndex + n] -= filtOut;
- }
-
- for (uint16_t n = sample2p5ms; n < lc3Config.NF; n++) {
- x_hat_ltpf_mem[blockStartIndex + n] = x_hat_mem[blockStartIndex + n];
- }
-
- } else {
- if ((p_int == p_int_mem) && (p_fr == p_fr_mem)) {
- //*** transition case 4 **********************************************
- for (uint16_t n = 0; n < lc3Config.NF; n++) {
- x_hat_ltpf_mem[blockStartIndex + n] = x_hat_mem[blockStartIndex + n];
- double filtOut = 0.0;
- for (uint16_t k = 0; k <= L_num; k++) {
- int16_t x_hat_index = blockStartIndex + n - k;
- if (x_hat_index < 0) {
- x_hat_index += numMemBlocks * lc3Config.NF;
- }
- filtOut += c_num[k] * x_hat_mem[x_hat_index];
- }
- for (uint16_t k = 0; k <= L_den; k++) {
- int16_t x_hat_ltpf_index =
- blockStartIndex + n - p_int + L_den / 2 - k;
- if (x_hat_ltpf_index < 0) {
- x_hat_ltpf_index += numMemBlocks * lc3Config.NF;
- }
- filtOut -= c_den[k] * x_hat_ltpf_mem[x_hat_ltpf_index];
- }
- x_hat_ltpf_mem[blockStartIndex + n] -= filtOut;
- }
-
- } else {
- //*** transition case 5 **********************************************
- for (uint16_t n = 0; n < sample2p5ms; n++) {
- x_hat_ltpf_mem[blockStartIndex + n] = x_hat_mem[blockStartIndex + n];
- double filtOut = 0.0;
- for (uint16_t k = 0; k <= L_num; k++) {
- int16_t x_hat_index = blockStartIndex + n - k;
- if (x_hat_index < 0) {
- x_hat_index += numMemBlocks * lc3Config.NF;
- }
- filtOut += c_num_mem[k] * x_hat_mem[x_hat_index];
- }
- for (uint16_t k = 0; k <= L_den; k++) {
- int16_t x_hat_ltpf_index =
- blockStartIndex + n - p_int_mem + L_den / 2 - k;
- if (x_hat_ltpf_index < 0) {
- x_hat_ltpf_index += numMemBlocks * lc3Config.NF;
- }
- filtOut -= c_den_mem[k] * x_hat_ltpf_mem[x_hat_ltpf_index];
- }
- filtOut *= 1 - (n / norm);
- x_hat_ltpf_mem[blockStartIndex + n] -= filtOut;
- }
-
- double x_hat_ltpf_temp[numMemBlocks *
- lc3Config.NF]; // is it good to place such a
- // buffer on the stack?
- for (int16_t m = -L_num; m < norm; m++) {
- int16_t idx = blockStartIndex + m;
- if (idx < 0) {
- idx += numMemBlocks * lc3Config.NF;
- }
- x_hat_ltpf_temp[idx] = x_hat_ltpf_mem[idx];
- }
-
- for (uint16_t n = 0; n < sample2p5ms; n++) {
- x_hat_ltpf_mem[blockStartIndex + n] =
- x_hat_ltpf_temp[blockStartIndex + n];
- double filtOut = 0.0;
- for (uint16_t k = 0; k <= L_num; k++) {
- int16_t x_hat_index = blockStartIndex + n - k;
- if (x_hat_index < 0) {
- x_hat_index += numMemBlocks * lc3Config.NF;
- }
- filtOut += c_num[k] * x_hat_ltpf_temp[x_hat_index];
- }
- for (uint16_t k = 0; k <= L_den; k++) {
- int16_t x_hat_ltpf_index =
- blockStartIndex + n - p_int + L_den / 2 - k;
- if (x_hat_ltpf_index < 0) {
- x_hat_ltpf_index += numMemBlocks * lc3Config.NF;
- }
- filtOut -= c_den[k] * x_hat_ltpf_mem[x_hat_ltpf_index];
- }
- filtOut *= (n / norm);
- x_hat_ltpf_mem[blockStartIndex + n] -= filtOut;
- }
-
- for (uint16_t n = sample2p5ms; n < lc3Config.NF; n++) {
- x_hat_ltpf_mem[blockStartIndex + n] = x_hat_mem[blockStartIndex + n];
- double filtOut = 0.0;
- for (uint16_t k = 0; k <= L_num; k++) {
- int16_t x_hat_index = blockStartIndex + n - k;
- if (x_hat_index < 0) {
- x_hat_index += numMemBlocks * lc3Config.NF;
- }
- filtOut += c_num[k] * x_hat_mem[x_hat_index];
- }
- for (uint16_t k = 0; k <= L_den; k++) {
- int16_t x_hat_ltpf_index =
- blockStartIndex + n - p_int + L_den / 2.0 - k;
- if (x_hat_ltpf_index < 0) {
- x_hat_ltpf_index += numMemBlocks * lc3Config.NF;
- }
- filtOut -= c_den[k] * x_hat_ltpf_mem[x_hat_ltpf_index];
- }
- x_hat_ltpf_mem[blockStartIndex + n] -= filtOut;
- }
- }
- }
-
- // copy to output x_hat_ltpf
- for (uint16_t n = 0; n < lc3Config.NF; n++) {
- x_hat_ltpf[n] = x_hat_ltpf_mem[blockStartIndex + n];
- }
-
- // increment current block in block-ringbuffer
- blockStartIndex += lc3Config.NF;
- if (blockStartIndex > (numMemBlocks - 1) * lc3Config.NF) {
- blockStartIndex = 0;
- }
-
- // register updates
- ltpf_active_prev = ltpf_active;
-}
-
-void LongTermPostfilter::registerDatapoints(DatapointContainer* datapoints) {
- if (nullptr != datapoints) {
- datapoints->addDatapoint("x_hat_ltpfin", x_hat_ltpfin,
- sizeof(double) * lc3Config.NF);
- datapoints->addDatapoint("x_hat_ltpf", x_hat_ltpf,
- sizeof(double) * lc3Config.NF);
- datapoints->addDatapoint("x_hat_ltpf_mem", x_hat_ltpf_mem,
- sizeof(double) * lc3Config.NF * numMemBlocks);
- datapoints->addDatapoint("x_hat_mem", x_hat_mem,
- sizeof(double) * lc3Config.NF * numMemBlocks);
- datapoints->addDatapoint("c_num", c_num, sizeof(double) * (L_num + 1));
- datapoints->addDatapoint("c_den", c_den, sizeof(double) * (L_den + 1));
- datapoints->addDatapoint("c_num_mem", c_num_mem,
- sizeof(double) * (L_num + 1));
- datapoints->addDatapoint("c_den_mem", c_den_mem,
- sizeof(double) * (L_den + 1));
- datapoints->addDatapoint("p_int", &p_int, sizeof(p_int));
- }
-}
-
-} // namespace Lc3Dec
diff --git a/system/embdrv/lc3_dec/Decoder/LongTermPostfilter.hpp b/system/embdrv/lc3_dec/Decoder/LongTermPostfilter.hpp
deleted file mode 100644
index daeb31aa7d..0000000000
--- a/system/embdrv/lc3_dec/Decoder/LongTermPostfilter.hpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * LongTermPostfilter.hpp
- *
- * 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.
- */
-
-#ifndef LONG_TERM_POSTFILTER_H_
-#define LONG_TERM_POSTFILTER_H_
-
-#include <cstdint>
-
-#include "Datapoints.hpp"
-#include "Lc3Config.hpp"
-
-namespace Lc3Dec {
-
-class LongTermPostfilter {
- public:
- LongTermPostfilter(const Lc3Config& lc3Config_, uint16_t nbits);
- ~LongTermPostfilter();
-
- void registerDatapoints(DatapointContainer* datapoints);
-
- LongTermPostfilter& operator=(const LongTermPostfilter&);
-
- void setInputX(const double* const x_hat);
- void run(int16_t ltpf_active, int16_t pitch_index);
-
- const Lc3Config& lc3Config;
- const uint8_t numMemBlocks;
- double* x_hat_ltpf;
-
- private:
- void setGainParams(uint16_t nbits);
- void computeFilterCoeffs(uint16_t pitch_index);
-
- int16_t ltpf_active_prev;
- uint16_t blockStartIndex;
- double* c_num;
- double* c_den;
- double* c_num_mem;
- double* c_den_mem;
- double* x_hat_ltpfin;
- double* x_hat_mem;
- double* x_hat_ltpf_mem;
-
- uint8_t L_num;
- uint8_t L_den;
-
- double gain_ltpf;
- uint8_t gain_ind;
-
- uint16_t p_int;
- uint16_t p_fr;
- uint16_t p_int_mem;
- uint16_t p_fr_mem;
-};
-
-} // namespace Lc3Dec
-
-#endif // LONG_TERM_POSTFILTER_H_
diff --git a/system/embdrv/lc3_dec/Decoder/MPVQ.cpp b/system/embdrv/lc3_dec/Decoder/MPVQ.cpp
deleted file mode 100644
index aa3d4d6b0a..0000000000
--- a/system/embdrv/lc3_dec/Decoder/MPVQ.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * MPVQ.cpp
- *
- * 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 "MPVQ.hpp"
-
-#include <cstdbool>
-
-#include "SnsQuantizationTables.hpp"
-
-namespace Lc3Dec {
-
-// declare local helper functions
-void mind2vec_tab(short dim_in, /* i: dimension */
- short k_max_local, /* i: nb unit pulses */
- short leading_sign, /* i: leading sign */
- unsigned int ind, /* i: MPVQ-index */
- short* vec_out, /* o: pulse train */
- unsigned int MPVQ_offsets[][11] /* i: offset matrix */
-);
-
-void mind2vec_one(short k_val_in, /* i: nb unit pulses */
- short leading_sign, /* i: leading sign -1, 1 */
- short* vec_out /* o: updated pulse train */
-);
-
-short setval_update_sign(short k_delta, /* i */
- short k_max_local_in, /* i */
- short* leading_sign, /* i/o */
- unsigned int* ind_in, /* i/o */
- short* vec_out /* i/o */
-);
-
-short get_lead_sign(unsigned int* ind_in);
-
-//
-// Implementation
-//
-
-void MPVQdeenum(uint8_t dim_in, /* i : dimension of vec_out */
- uint8_t k_val_in, /* i : number of unit pulses */
- int16_t LS_ind, /* i : leading sign index */
- int32_t MPVQ_ind, /* i : MPVQ shape index */
- int16_t* vec_out /* o : PVQ integer pulse train */
-) {
- for (uint8_t i = 0; i < dim_in; i++) {
- vec_out[i] = 0;
- }
- short leading_sign = 1;
- if (LS_ind != 0) {
- leading_sign = -1;
- }
- mind2vec_tab(dim_in, k_val_in, leading_sign, MPVQ_ind, vec_out, MPVQ_offsets);
-}
-
-void mind2vec_tab(short dim_in, /* i: dimension */
- short k_max_local, /* i: nb unit pulses */
- short leading_sign, /* i: leading sign */
- unsigned int ind, /* i: MPVQ-index */
- short* vec_out, /* o: pulse train */
- unsigned int MPVQ_offsets[][11] /* i: offset matrix */
-) {
- /* init */
- unsigned int* h_row_ptr = &(MPVQ_offsets[(dim_in - 1)][0]);
- short k_acc = k_max_local;
- /* loop over positions */
- for (uint8_t pos = 0; pos < dim_in; pos++) {
- short k_delta;
- if (ind != 0) {
- k_acc = k_max_local;
- ;
- unsigned int UL_tmp_offset = h_row_ptr[k_acc];
- bool wrap_flag = (ind < UL_tmp_offset);
- unsigned int UL_diff = 0;
- if (!wrap_flag) {
- // Note: due to android build using a integer-overflow sanitizer, we
- // have to avoid
- // computing the following difference when ind < UL_tmp_offset
- UL_diff = ind - UL_tmp_offset;
- }
- while (wrap_flag) {
- k_acc--;
- wrap_flag = (ind < h_row_ptr[k_acc]);
- if (!wrap_flag) {
- // Note: due to android build using a integer-overflow sanitizer, we
- // have to avoid
- // computing the following difference when ind < UL_tmp_offset
- UL_diff = ind - h_row_ptr[k_acc];
- }
- }
- ind = UL_diff;
- k_delta = k_max_local - k_acc;
- } else {
- mind2vec_one(k_max_local, leading_sign, &vec_out[pos]);
- break;
- }
- k_max_local = setval_update_sign(k_delta, k_max_local, &leading_sign, &ind,
- &vec_out[pos]);
- h_row_ptr -= 11; /* reduce dimension in MPVQ_offsets table */
- }
-}
-
-void mind2vec_one(short k_val_in, /* i: nb unit pulses */
- short leading_sign, /* i: leading sign -1, 1 */
- short* vec_out /* o: updated pulse train */
-) {
- short amp = k_val_in;
- if (leading_sign < 0) {
- amp = -k_val_in;
- }
- *vec_out = amp;
-}
-
-short setval_update_sign(
- short k_delta, /* i */
- short k_max_local_in, /* i */
- short* leading_sign, /* i/o */
- unsigned int* ind_in, /* i/o; needed to change type compared to spec */
- short* vec_out /* i/o */
-) {
- short k_max_local_out = k_max_local_in;
- if (k_delta != 0) {
- mind2vec_one(k_delta, *leading_sign, vec_out);
- *leading_sign = get_lead_sign(ind_in);
- k_max_local_out -= k_delta;
- }
- return k_max_local_out;
-}
-
-short get_lead_sign(
- unsigned int* ind) // renamed "ind_in" from spec to just "ind" (as already
- // found by yao.wang 28.06.2019)
-{
- short leading_sign = +1;
- if (((*ind) & 0x1) != 0) {
- leading_sign = -1;
- }
- (*ind) = (*ind >> 1);
- return leading_sign;
-}
-
-} // namespace Lc3Dec
diff --git a/system/embdrv/lc3_dec/Decoder/MPVQ.hpp b/system/embdrv/lc3_dec/Decoder/MPVQ.hpp
deleted file mode 100644
index e015d65c2b..0000000000
--- a/system/embdrv/lc3_dec/Decoder/MPVQ.hpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * MPVQ.hpp
- *
- * 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.
- */
-
-#ifndef __MPVQ_HPP_
-#define __MPVQ_HPP_
-
-#include <cstdint>
-
-namespace Lc3Dec {
-
-void MPVQdeenum(uint8_t dim_in, /* i : dimension of vec_out */
- uint8_t k_val_in, /* i : number of unit pulses */
- int16_t LS_ind, /* i : leading sign index */
- int32_t MPVQ_ind, /* i : MPVQ shape index */
- int16_t* vec_out /* o : PVQ integer pulse train */
-);
-
-} // namespace Lc3Dec
-
-#endif // __MPVQ_HPP_
diff --git a/system/embdrv/lc3_dec/Decoder/MdctDec.cpp b/system/embdrv/lc3_dec/Decoder/MdctDec.cpp
deleted file mode 100644
index ba56b5d5d9..0000000000
--- a/system/embdrv/lc3_dec/Decoder/MdctDec.cpp
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * MdctDec.cpp
- *
- * 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 "MdctDec.hpp"
-
-#include <cmath>
-
-#include "MdctWindows.hpp"
-
-namespace Lc3Dec {
-
-MdctDec::MdctDec(const Lc3Config& lc3Config_)
- : lc3Config(lc3Config_),
- x_hat_mdct(nullptr),
- dctIVDbl(lc3Config.NF),
- mem_ola_add(nullptr),
- t_hat_mdct(nullptr),
- wN(nullptr) {
- mem_ola_add = new double[lc3Config.NF - lc3Config.Z];
- t_hat_mdct = new double[2 * lc3Config.NF];
- x_hat_mdct = new double[lc3Config.NF];
- for (uint16_t n = 0; n < (lc3Config.NF - lc3Config.Z); n++) {
- mem_ola_add[n] = 0;
- }
-
- // Note: we do not add additional configuration error checking at this level.
- // We assume that there will be nor processing with invalid configuration,
- // thus nonsense results for invalid lc3Config.N_ms and/or lc3Config.Fs_ind
- // are accepted here.
- wN = w_N80; // default initialization to avoid warnings
- if (lc3Config.N_ms == Lc3Config::FrameDuration::d7p5ms) {
- switch (lc3Config.NF) {
- case 60:
- wN = w_N60_7p5ms;
- break;
- case 120:
- wN = w_N120_7p5ms;
- break;
- case 180:
- wN = w_N180_7p5ms;
- break;
- case 240:
- wN = w_N240_7p5ms;
- break;
- case 360:
- wN = w_N360_7p5ms;
- break;
- }
- } else {
- // Lc3Config::FrameDuration::d10ms (and other as fallback)
- switch (lc3Config.NF) {
- case 80:
- wN = w_N80;
- break;
- case 160:
- wN = w_N160;
- break;
- case 240:
- wN = w_N240;
- break;
- case 320:
- wN = w_N320;
- break;
- case 480:
- wN = w_N480;
- break;
- }
- }
-}
-
-MdctDec::~MdctDec() {
- if (nullptr != mem_ola_add) {
- delete[] mem_ola_add;
- }
- if (nullptr != t_hat_mdct) {
- delete[] t_hat_mdct;
- }
- if (nullptr != x_hat_mdct) {
- delete[] x_hat_mdct;
- }
-}
-
-void MdctDec::MdctInvFastDbl() {
- dctIVDbl.run();
-
- for (uint16_t n = 0; n < lc3Config.NF; n++) {
- t_hat_mdct[n] = dctIVDbl.out[n];
- }
- for (uint16_t n = lc3Config.NF; n < 2 * lc3Config.NF; n++) {
- t_hat_mdct[n] = -dctIVDbl.out[2 * lc3Config.NF - 1 - n];
- }
-
- // TODO try to optimize out the mem-buffer
- double mem[lc3Config.NF / 2];
- for (uint16_t n = 0; n < lc3Config.NF / 2; n++) {
- mem[n] = t_hat_mdct[n];
- }
- for (uint16_t n = 0; n < 3 * lc3Config.NF / 2; n++) {
- t_hat_mdct[n] = t_hat_mdct[n + lc3Config.NF / 2];
- }
- for (uint16_t n = 3 * lc3Config.NF / 2; n < 2 * lc3Config.NF; n++) {
- t_hat_mdct[n] = -mem[n - 3 * lc3Config.NF / 2];
- }
-
- double gain = 1.0 / sqrt(2.0 * lc3Config.NF);
- for (uint16_t n = 0; n < 2 * lc3Config.NF; n++) {
- t_hat_mdct[n] *= gain;
- }
-}
-
-void MdctDec::run(const double* const X_hat) {
- if (!lc3Config.isValid()) {
- return;
- }
-
- for (uint16_t k = 0; k < lc3Config.NE; k++) {
- dctIVDbl.in[k] = X_hat[k];
- }
- for (uint16_t k = lc3Config.NE; k < lc3Config.NF; k++) {
- dctIVDbl.in[k] = 0;
- }
-
- // 1. Generation of time domain aliasing buffer
- MdctInvFastDbl();
-
- // 2. Windowing of time-aliased buffer
- for (uint16_t n = 0; n < 2 * lc3Config.NF; n++) {
- t_hat_mdct[n] *= wN[2 * lc3Config.NF - 1 - n];
- }
-
- // 3. Conduct overlapp-add operation
- for (uint16_t n = 0; n < lc3Config.NF - lc3Config.Z; n++) {
- x_hat_mdct[n] = mem_ola_add[n] + t_hat_mdct[lc3Config.Z + n];
- mem_ola_add[n] = t_hat_mdct[lc3Config.NF + lc3Config.Z + n];
- }
- for (uint16_t n = lc3Config.NF - lc3Config.Z; n < lc3Config.NF; n++) {
- x_hat_mdct[n] = t_hat_mdct[lc3Config.Z + n];
- }
-}
-
-void MdctDec::registerDatapoints(DatapointContainer* datapoints) {
- if (nullptr != datapoints) {
- datapoints->addDatapoint("X_hat_mdct", dctIVDbl.in,
- sizeof(double) * lc3Config.NF);
- datapoints->addDatapoint("t_hat_mdct", t_hat_mdct,
- sizeof(double) * 2 * lc3Config.NF);
- datapoints->addDatapoint("mem_ola_add", mem_ola_add,
- sizeof(double) * (lc3Config.NF - lc3Config.Z));
- datapoints->addDatapoint("x_hat_mdct", x_hat_mdct,
- sizeof(double) * lc3Config.NF);
- }
-}
-
-} // namespace Lc3Dec
diff --git a/system/embdrv/lc3_dec/Decoder/MdctDec.hpp b/system/embdrv/lc3_dec/Decoder/MdctDec.hpp
deleted file mode 100644
index 86e3ab654c..0000000000
--- a/system/embdrv/lc3_dec/Decoder/MdctDec.hpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * MdctDec.hpp
- *
- * 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.
- */
-
-#ifndef MDCT_DEC_H_
-#define MDCT_DEC_H_
-
-#include <cstdint>
-
-#include "Datapoints.hpp"
-#include "DctIV.hpp"
-#include "Lc3Config.hpp"
-
-namespace Lc3Dec {
-
-class MdctDec {
- public:
- MdctDec(const Lc3Config& lc3Config_);
- virtual ~MdctDec();
-
- void registerDatapoints(DatapointContainer* datapoints);
-
- void run(const double* const X_hat);
-
- const Lc3Config& lc3Config;
- double* x_hat_mdct;
-
- private:
- void MdctInvFastDbl();
-
- DctIVDbl dctIVDbl;
- double* mem_ola_add;
- double* t_hat_mdct;
- double* wN;
-};
-
-} // namespace Lc3Dec
-
-#endif // MDCT_DEC_H_
diff --git a/system/embdrv/lc3_dec/Decoder/PacketLossConcealment.cpp b/system/embdrv/lc3_dec/Decoder/PacketLossConcealment.cpp
deleted file mode 100644
index 0d038808d5..0000000000
--- a/system/embdrv/lc3_dec/Decoder/PacketLossConcealment.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * PacketLossConcealment.cpp
- *
- * 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 "PacketLossConcealment.hpp"
-
-namespace Lc3Dec {
-
-PacketLossConcealment::PacketLossConcealment(uint16_t NE_)
- : NE(NE_),
- plc_seed(24607), // this initialization need not be done every frame as
- // clarified by Errata 15114
- nbLostCmpt(0),
- alpha(1),
- X_hat_lastGood(nullptr) {
- X_hat_lastGood = new double[NE];
- for (uint16_t k = 0; k < NE; k++) {
- X_hat_lastGood[k] = 0.0;
- }
-}
-
-PacketLossConcealment::~PacketLossConcealment() { delete[] X_hat_lastGood; }
-
-void PacketLossConcealment::run(uint8_t BEC_detect, double* X_hat,
- int16_t& ltpf_active) {
- // Appendix B. Packet Loss Concealment (d09r02_F2F)
- if (0 == BEC_detect) {
- nbLostCmpt = 0;
- alpha = 1;
- for (uint16_t k = 0; k < NE; k++) {
- X_hat_lastGood[k] = X_hat[k];
- }
- } else {
- ltpf_active = 0; // errata 15097 implemented
-
- if (nbLostCmpt < 0xFF) {
- nbLostCmpt++;
- }
-
- // Note: from (d09r02_F2F) its is not perfectly clear,
- // whether alpha is modified before or after applying
- // it to the spectrum -> we may have to check the
- // given implementation with the LC3.exe reference
- if (nbLostCmpt >= 8) {
- alpha = 0.85 * alpha;
- } else if (nbLostCmpt >= 4) {
- alpha = 0.9 * alpha;
- }
-
- for (uint16_t k = 0; k < NE; k++) {
- plc_seed = (16831 + plc_seed * 12821) & 0xFFFF;
- if (plc_seed < 0x8000) {
- X_hat[k] = alpha * X_hat_lastGood[k];
- } else {
- X_hat[k] = -alpha * X_hat_lastGood[k];
- }
- }
- }
-}
-
-void PacketLossConcealment::registerDatapoints(DatapointContainer* datapoints) {
- if (nullptr != datapoints) {
- datapoints->addDatapoint("X_hat_lastGood", &X_hat_lastGood[0],
- sizeof(double) * NE);
- }
-}
-
-} // namespace Lc3Dec
diff --git a/system/embdrv/lc3_dec/Decoder/PacketLossConcealment.hpp b/system/embdrv/lc3_dec/Decoder/PacketLossConcealment.hpp
deleted file mode 100644
index e3eb0679bd..0000000000
--- a/system/embdrv/lc3_dec/Decoder/PacketLossConcealment.hpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * PacketLossConcealment.hpp
- *
- * 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.
- */
-
-#ifndef PACKET_LOSS_CONCEALMENT_H_
-#define PACKET_LOSS_CONCEALMENT_H_
-
-#include <cstdint>
-
-#include "Datapoints.hpp"
-
-namespace Lc3Dec {
-
-class PacketLossConcealment {
- public:
- PacketLossConcealment(uint16_t NE_);
- virtual ~PacketLossConcealment();
-
- void registerDatapoints(DatapointContainer* datapoints);
-
- void run(uint8_t BER_DETECT, double* X_hat, int16_t& ltpf_active);
-
- const uint16_t NE;
-
- private:
- uint16_t plc_seed;
- uint8_t nbLostCmpt;
- double alpha;
- double* X_hat_lastGood;
-};
-
-} // namespace Lc3Dec
-
-#endif // PACKET_LOSS_CONCEALMENT_H_
diff --git a/system/embdrv/lc3_dec/Decoder/ResidualSpectrum.cpp b/system/embdrv/lc3_dec/Decoder/ResidualSpectrum.cpp
deleted file mode 100644
index 55453ad32f..0000000000
--- a/system/embdrv/lc3_dec/Decoder/ResidualSpectrum.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * ResidualSpectrum.cpp
- *
- * 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 "ResidualSpectrum.hpp"
-
-#include <cmath>
-
-#include "BitReader.hpp"
-
-namespace Lc3Dec {
-
-ResidualSpectrum::ResidualSpectrum(uint16_t NE_)
- : NE(NE_), X_hat_q_residual(nullptr), nResBits(0) {
- X_hat_q_residual = new double[NE];
-}
-
-ResidualSpectrum::~ResidualSpectrum() { delete[] X_hat_q_residual; }
-
-void ResidualSpectrum::run(
- const uint8_t* bytes, uint16_t& bp_side, uint8_t& mask_side,
- const uint16_t lastnz, const int16_t* const X_hat_q_ari,
- uint16_t const nbits_residual, // the const is implementation dependent and
- // thus not repeated in header declaration
- uint8_t* save_lev, const uint8_t& lsbMode, uint16_t& nf_seed,
- uint16_t& zeroFrame, const int16_t gg_ind, int16_t F_NF) {
- // 3.4.2.6 Residual data and finalization (d09r02_F2F)
- /* Decode residual bits */
- for (uint16_t k = 0; k < lastnz; k++) {
- X_hat_q_residual[k] = X_hat_q_ari[k];
- }
- // for (k = lastnz; k < 𝑁𝐸; k++)
- for (uint16_t k = lastnz; k < NE; k++) {
- //𝑋𝑞 ̂[k] = 0;
- X_hat_q_residual[k] = 0;
- }
- uint8_t resBits[nbits_residual];
- uint16_t remaining_nbits_residual =
- nbits_residual; // changed relative to specification to ensure const
- // input into array allocation
- nResBits = 0;
- if (lsbMode == 0) {
- // for (k = 0; k < 𝑁𝐸; k++)
- for (uint16_t k = 0; k < NE; k++) {
- // if (𝑋𝑞 ̂[k] != 0)
- if (X_hat_q_residual[k] != 0) {
- if (nResBits == remaining_nbits_residual) {
- break;
- }
- resBits[nResBits++] = read_bit(bytes, &bp_side, &mask_side);
- }
- }
- } else {
- for (uint16_t k = 0; k < lastnz; k += 2) {
- if (save_lev[k] > 0) {
- if (remaining_nbits_residual == 0) {
- break;
- }
- uint8_t bit = read_bit(bytes, &bp_side, &mask_side);
- remaining_nbits_residual--;
- if (bit == 1) {
- // if (𝑋𝑞 ̂[k] > 0)
- if (X_hat_q_residual[k] > 0) {
- //𝑋𝑞 ̂[k] += 1;
- X_hat_q_residual[k] += 1;
- }
- // else if (𝑋𝑞 ̂[k] < 0)
- else if (X_hat_q_residual[k] < 0) {
- //𝑋𝑞 ̂[k] -= 1;
- X_hat_q_residual[k] -= 1;
- } else {
- if (remaining_nbits_residual == 0) {
- break;
- }
- bit = read_bit(bytes, &bp_side, &mask_side);
- remaining_nbits_residual--;
- if (bit == 0) {
- //𝑋𝑞 ̂[k] = 1;
- X_hat_q_residual[k] = 1;
- } else {
- //𝑋𝑞 ̂[k] = -1;
- X_hat_q_residual[k] = -1;
- }
- }
- }
- if (remaining_nbits_residual == 0) {
- break;
- }
- bit = read_bit(bytes, &bp_side, &mask_side);
- remaining_nbits_residual--;
- if (bit == 1) {
- // if (𝑋𝑞 ̂[k+1] > 0)
- if (X_hat_q_residual[k + 1] > 0) {
- //𝑋𝑞 ̂[k+1] += 1;
- X_hat_q_residual[k + 1] += 1;
- }
- // else if (𝑋𝑞 ̂[k+1] < 0)
- else if (X_hat_q_residual[k + 1] < 0) {
- //𝑋𝑞 ̂[k+1] -= 1;
- X_hat_q_residual[k + 1] -= 1;
- } else {
- if (remaining_nbits_residual == 0) {
- break;
- }
- bit = read_bit(bytes, &bp_side, &mask_side);
- remaining_nbits_residual--;
- if (bit == 0) {
- //𝑋𝑞 ̂[k+1] = 1;
- X_hat_q_residual[k + 1] = 1;
- } else {
- //𝑋𝑞 ̂[k+1] = -1;
- X_hat_q_residual[k + 1] = -1;
- }
- }
- }
- }
- }
- }
-
- /* Noise Filling Seed */
- int16_t tmp = 0;
- // for (k = 0; k < 𝑁𝐸; k++)
- for (uint16_t k = 0; k < NE; k++) {
- // tmp += abs(𝑋𝑞 ̂[k]) * k;
- tmp += abs(X_hat_q_residual[k]) * k;
- }
- nf_seed = tmp & 0xFFFF; /* Note that both tmp and nf_seed are 32-bit int*/
- /* Zero frame flag */
- // if (lastnz == 2 && 𝑋𝑞 ̂[0] == 0 && 𝑋𝑞 ̂[1] == 0 && 𝑔𝑔𝑖𝑛𝑑 == 0 && 𝐹𝑁𝐹 == 7)
- if ((lastnz == 2) && (X_hat_q_residual[0] == 0.0) &&
- (X_hat_q_residual[1] == 0.0) && (gg_ind == 0) && (F_NF == 7)) {
- zeroFrame = 1;
- } else {
- zeroFrame = 0;
- }
-
- // 3.4.3 Residual decoding (d09r02_F2F)
- // Residual decoding is performed only when lsbMode is 0.
- if (lsbMode == 0) {
- uint16_t k, n;
- k = n = 0;
- // while (k < 𝑁𝐸 && n < nResBits)
- while (k < NE && n < nResBits) {
- // if (𝑋𝑞 ̂[k] != 0)
- if (X_hat_q_residual[k] != 0) {
- if (resBits[n++] == 0) {
- // if (𝑋𝑞 ̂[k] > 0)
- if (X_hat_q_residual[k] > 0) {
- //𝑋𝑞 ̂[k] -= 0.1875;
- X_hat_q_residual[k] -= 0.1875;
- } else {
- //𝑋𝑞 ̂[k] -= 0.3125;
- X_hat_q_residual[k] -= 0.3125;
- }
- } else {
- // if (𝑋𝑞 ̂[k] > 0)
- if (X_hat_q_residual[k] > 0) {
- //𝑋𝑞 ̂[k] += 0.3125;
- X_hat_q_residual[k] += 0.3125;
- } else {
- //𝑋𝑞 ̂[k] += 0.1875;
- X_hat_q_residual[k] += 0.1875;
- }
- }
- }
- k++;
- }
- }
-}
-
-void ResidualSpectrum::registerDatapoints(DatapointContainer* datapoints) {
- if (nullptr != datapoints) {
- datapoints->addDatapoint("X_hat_q_residual", &X_hat_q_residual[0],
- sizeof(double) * NE);
- }
-}
-
-} // namespace Lc3Dec
diff --git a/system/embdrv/lc3_dec/Decoder/ResidualSpectrum.hpp b/system/embdrv/lc3_dec/Decoder/ResidualSpectrum.hpp
deleted file mode 100644
index 2f13a57023..0000000000
--- a/system/embdrv/lc3_dec/Decoder/ResidualSpectrum.hpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * ResidualSpectrum.hpp
- *
- * 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.
- */
-
-#ifndef RESIDUAL_SPECTRUM_H_
-#define RESIDUAL_SPECTRUM_H_
-
-#include <cstdint>
-
-#include "Datapoints.hpp"
-
-namespace Lc3Dec {
-
-class ResidualSpectrum {
- public:
- ResidualSpectrum(uint16_t NE_);
-
- virtual ~ResidualSpectrum();
-
- void registerDatapoints(DatapointContainer* datapoints);
-
- void run(const uint8_t* bytes, uint16_t& bp_side, uint8_t& mask_side,
- const uint16_t lastnz, const int16_t* const X_hat_q_ari,
- uint16_t nbits_residual, uint8_t* save_lev, const uint8_t& lsbMode,
- uint16_t& nf_seed, uint16_t& zeroFrame, const int16_t gg_ind,
- int16_t F_NF);
-
- const uint16_t NE;
-
- double* X_hat_q_residual;
- uint16_t nResBits;
-
- private:
-};
-
-} // namespace Lc3Dec
-
-#endif // RESIDUAL_SPECTRUM_H_
diff --git a/system/embdrv/lc3_dec/Decoder/SideInformation.cpp b/system/embdrv/lc3_dec/Decoder/SideInformation.cpp
deleted file mode 100644
index 4516aabf60..0000000000
--- a/system/embdrv/lc3_dec/Decoder/SideInformation.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * SideInformation.cpp
- *
- * 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 "SideInformation.hpp"
-
-#include <cmath>
-
-#include "BitReader.hpp"
-
-namespace Lc3Dec {
-
-static const uint8_t nbits_bw_table[5] = {
- 0, 1, 2, 2, 3}; // see 3.4.2.4 Bandwidth interpretation (d09r02_F2F)
-
-SideInformation::SideInformation(uint16_t NF_, uint16_t NE_, uint8_t fs_ind_)
- : NF(NF_),
- NE(NE_),
- fs_ind(fs_ind_),
- nbits_bw(nbits_bw_table[fs_ind]),
- submodeMSB(0),
- submodeLSB(0) {}
-
-SideInformation::~SideInformation() {}
-
-void SideInformation::dec_split_st2VQ_CW(uint32_t cwRx, uint32_t szA,
- uint32_t szB, uint8_t& BEC_detect,
- int16_t& submodeLSB, int32_t& idxA,
- int32_t& idxBorGainLSB) {
- if (cwRx >= szB * szA) {
- idxA = 0;
- idxBorGainLSB = 0;
- submodeLSB = 0;
- BEC_detect = 1;
- return;
- }
- idxBorGainLSB = floor(cwRx / szA);
- idxA = cwRx - idxBorGainLSB * szA;
- submodeLSB = 0;
- idxBorGainLSB = idxBorGainLSB - 2;
- if (idxBorGainLSB < 0) {
- submodeLSB = 1;
- }
-
- idxBorGainLSB = idxBorGainLSB + 2 * submodeLSB;
- // BEC_detect = 0; // changed in comparision to specification -> variable is
- // handles as reference to overall BEC_detect
-}
-
-void SideInformation::run(const uint8_t* bytes, uint16_t& bp_side,
- uint8_t& mask_side, int16_t& P_BW, int16_t& lastnz,
- uint8_t& lsbMode, int16_t& gg_ind,
- int16_t& num_tns_filters, int16_t* rc_order,
- uint8_t& pitch_present, int16_t& pitch_index,
- int16_t& ltpf_active, int16_t& F_NF, int16_t& ind_LF,
- int16_t& ind_HF, int16_t& Gind, int16_t& LS_indA,
- int16_t& LS_indB, int32_t& idxA, int16_t& idxB,
-
- uint8_t& BEC_detect) {
- // 5.4.2.3 Side information
- /* Bandwidth */
- if (nbits_bw > 0) {
- P_BW = read_uint(bytes, &bp_side, &mask_side, nbits_bw);
- if (fs_ind < P_BW) {
- BEC_detect = 1;
- return;
- }
- } else {
- P_BW = 0;
- }
- /* Last non-zero tuple */
- nbits_lastnz = ceil(log2(NE / 2));
- int16_t tmp_lastnz = read_uint(bytes, &bp_side, &mask_side, nbits_lastnz);
- lastnz = (tmp_lastnz + 1) << 1;
- if (lastnz > NE) {
- /* consider this as bit error (BEC) */
- BEC_detect = 1;
- return;
- }
- /* LSB mode bit */
- lsbMode = read_bit(bytes, &bp_side, &mask_side);
- /* Global Gain */
- gg_ind = read_uint(bytes, &bp_side, &mask_side, 8);
- /* TNS activation flag */
- if (P_BW < 3) {
- num_tns_filters = 1;
- } else {
- num_tns_filters = 2;
- }
- rc_order[0] = 0; // not specified, but on the safe side
- rc_order[1] = 0; // not specified, but on the safe side
- for (uint8_t f = 0; f < num_tns_filters; f++) {
- rc_order[f] = read_bit(bytes, &bp_side, &mask_side);
- }
- /* Pitch present flag */
- pitch_present = read_bit(bytes, &bp_side, &mask_side);
- /* SNS-VQ integer bits */
- /* Read 5+5 bits of SNQ VQ decoding stage 1 according to Section 5.4.7.2.1
- * (d09r01) */
- /* Read 5+5 bits of SNQ VQ decoding stage 1 according to Section 3.4.7.2.1
- * (d09r02)(d09r02_F2F) */
- ind_LF = read_uint(bytes, &bp_side, &mask_side, 5); /* stage1 LF */
- ind_HF = read_uint(bytes, &bp_side, &mask_side, 5); /* stage1 HF */
-
- /* Read 28 bits of SNS VQ decoding stage 2 according to section 5.4.7.2.2
- * (d09r01) */
- // 3.4.7.2.2 Stage 2 SNS VQ decoding (d09r02_F2F)
- submodeMSB = read_bit(bytes, &bp_side, &mask_side);
- if (submodeMSB == 0) {
- Gind = read_uint(bytes, &bp_side, &mask_side, 1);
- } else {
- Gind = read_uint(bytes, &bp_side, &mask_side, 2);
- }
- LS_indA = read_bit(bytes, &bp_side, &mask_side); /* LS_indA 1 bit */
- if (submodeMSB == 0) {
- /* ‘regular’/’regular_lf’ demultiplexing, establish if shape_j is 0 or 1 */
- uint32_t tmp = read_uint(bytes, &bp_side, &mask_side, 13);
- tmp |= (read_uint(bytes, &bp_side, &mask_side, 12) << 13);
- int32_t idxBorGainLSB;
- //[ BEC_detect, submodeLSB, idxA, idxBorGainLSB ] = dec_split_st2VQ_CW(tmp,
- // 4780008U>>1, 14 );
- dec_split_st2VQ_CW(tmp, 4780008U >> 1, 14, BEC_detect, submodeLSB, idxA,
- idxBorGainLSB);
- if (BEC_detect) {
- // early exit to avoid unpredictable side-effects
- return;
- }
- if (submodeLSB != 0) {
- Gind = (Gind << 1) + idxBorGainLSB; /* for regular_lf */
- // just set some defined values (although nothing is specified for this
- // case)
- idxB = 0;
- LS_indB = 0;
- } else {
- idxB = idxBorGainLSB >> 1; /* for regular */
- LS_indB = idxBorGainLSB & 0x1;
- }
- } else {
- // Attention: the given reference intermediate results do not cover
- // this case -> tested with conformance tests only! (successful operation
- // observed already)
- /* outlier_* demultiplexing, establish if shape_j is 2 or 3 */
- int32_t tmp = read_uint(bytes, &bp_side, &mask_side, 12);
- tmp |=
- static_cast<int32_t>(read_uint(bytes, &bp_side, &mask_side, 12) << 12);
- idxA = tmp;
- // idxB = -1; // removed in pseudo-code of d09r02_F2F
- submodeLSB = 0;
- // this intialization does not seem to be correct here
- // (just from code reading; context of pseudo-code in specification is not
- // clear)
- // BEC_detect = 0;
- if (tmp >= static_cast<int32_t>((30316544U >> 1) + 1549824U)) {
- BEC_detect = 1;
- return;
- } else {
- tmp -= static_cast<int32_t>(30316544U >> 1);
- if (tmp >= 0) {
- submodeLSB = 1;
- Gind = (Gind << 1) + (tmp & 0x1);
- idxA = tmp >> 1;
- }
- }
- }
-
- /* LTPF data */
- if (pitch_present != 0) {
- ltpf_active = read_uint(bytes, &bp_side, &mask_side, 1);
- pitch_index = read_uint(bytes, &bp_side, &mask_side, 9);
- }
-
- /* Noise Level */
- F_NF = read_uint(bytes, &bp_side, &mask_side, 3);
-}
-
-void SideInformation::registerDatapoints(DatapointContainer* datapoints) {
- if (nullptr != datapoints) {
- datapoints->addDatapoint("nbits_lastnz", &nbits_lastnz,
- sizeof(nbits_lastnz));
- datapoints->addDatapoint("submodeMSB", &submodeMSB, sizeof(submodeMSB));
- }
-}
-
-} // namespace Lc3Dec
diff --git a/system/embdrv/lc3_dec/Decoder/SideInformation.hpp b/system/embdrv/lc3_dec/Decoder/SideInformation.hpp
deleted file mode 100644
index e6df7e4960..0000000000
--- a/system/embdrv/lc3_dec/Decoder/SideInformation.hpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * SideInformation.hpp
- *
- * 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.
- */
-
-#ifndef SIDE_INFORMATION_H_
-#define SIDE_INFORMATION_H_
-
-#include <cstdint>
-
-#include "Datapoints.hpp"
-
-namespace Lc3Dec {
-
-class SideInformation {
- public:
- SideInformation(uint16_t NF_, uint16_t NE_, uint8_t fs_ind_);
-
- virtual ~SideInformation();
-
- void registerDatapoints(DatapointContainer* datapoints);
-
- void run(const uint8_t* bytes, uint16_t& bp_side, uint8_t& mask_side,
- int16_t& P_BW, int16_t& lastnz, uint8_t& lsbMode, int16_t& gg_ind,
- int16_t& num_tns_filters, int16_t* rc_order, uint8_t& pitch_present,
- int16_t& pitch_index, int16_t& ltpf_active, int16_t& F_NF,
- int16_t& ind_LF, int16_t& ind_HF, int16_t& Gind, int16_t& LS_indA,
- int16_t& LS_indB, int32_t& idxA, int16_t& idxB,
-
- uint8_t& BEC_detect);
-
- const uint16_t NF;
- const uint16_t NE;
- const uint8_t fs_ind;
- const uint8_t nbits_bw;
-
- int16_t submodeMSB;
- int16_t submodeLSB;
-
- private:
- uint8_t nbits_lastnz;
-
- void dec_split_st2VQ_CW(uint32_t cwRx, uint32_t szA, uint32_t szB,
- uint8_t& BEC_detect, int16_t& submodeLSB,
- int32_t& idxA, int32_t& idxBorGainLSB);
-};
-
-} // namespace Lc3Dec
-
-#endif // SIDE_INFORMATION_H_
diff --git a/system/embdrv/lc3_dec/Decoder/SpectralNoiseShaping.cpp b/system/embdrv/lc3_dec/Decoder/SpectralNoiseShaping.cpp
deleted file mode 100644
index b07de9d6a3..0000000000
--- a/system/embdrv/lc3_dec/Decoder/SpectralNoiseShaping.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * SpectralNoiseShaping.cpp
- *
- * 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 "SpectralNoiseShaping.hpp"
-
-#include <cmath>
-
-#include "BandIndexTables.hpp"
-#include "MPVQ.hpp"
-#include "SnsQuantizationTables.hpp"
-
-namespace Lc3Dec {
-
-SpectralNoiseShaping::SpectralNoiseShaping(const Lc3Config& lc3Config_)
- : lc3Config(lc3Config_), I_fs(nullptr) {
- // Note: we do not add additional configuration error checking at this level.
- // We assume that there will be nor processing with invalid configuration,
- // thus nonsense results for invalid lc3Config.N_ms and/or lc3Config.Fs_ind
- // are accepted here.
- if (lc3Config.N_ms == Lc3Config::FrameDuration::d7p5ms) {
- switch (lc3Config.Fs_ind) {
- case 0:
- I_fs = &I_8000_7p5ms[0];
- break;
- case 1:
- I_fs = &I_16000_7p5ms[0];
- break;
- case 2:
- I_fs = &I_24000_7p5ms[0];
- break;
- case 3:
- I_fs = &I_32000_7p5ms[0];
- break;
- case 4:
- I_fs = &I_48000_7p5ms[0];
- break;
- }
- } else {
- // Lc3Config::FrameDuration::d10ms (and other as fallback)
- switch (lc3Config.Fs_ind) {
- case 0:
- I_fs = &I_8000[0];
- break;
- case 1:
- I_fs = &I_16000[0];
- break;
- case 2:
- I_fs = &I_24000[0];
- break;
- case 3:
- I_fs = &I_32000[0];
- break;
- case 4:
- I_fs = &I_48000[0];
- break;
- }
- }
-}
-
-SpectralNoiseShaping::~SpectralNoiseShaping() {}
-
-void SpectralNoiseShaping::run(const double* const X_s_tns,
- double* const X_hat_ss, int16_t ind_LF,
- int16_t ind_HF, int16_t submodeMSB,
- int16_t submodeLSB, int16_t Gind,
- int16_t LS_indA, int16_t LS_indB, int32_t idxA,
- int16_t idxB) {
- if (!lc3Config.isValid()) {
- return;
- }
-
- // 3.4.7 SNS decoder (d09r02_F2F)
- // 3.4.7.2 SNS scale factor decoding (d09r02_F2F)
- // 3.4.7.2.1 Stage 1 SNS VQ decoding (d09r02_F2F)
- // already done earlier (see SideInformation)
-
- // The first stage vector is composed as:
- //𝑠𝑡1(𝑛) = 𝐿𝐹𝐶𝐵𝑖𝑛𝑑_𝐿𝐹 (𝑛), 𝑓𝑜𝑟 𝑛 = [0 … 7], # (33)
- //𝑠𝑡1(𝑛 + 8) = 𝐻𝐹𝐶𝐵𝑖𝑛𝑑_𝐻𝐹(𝑛), 𝑓𝑜𝑟 𝑛 = [0 … 7], # (34)
- double st1[16];
- for (uint8_t n = 0; n < 8; n++) {
- st1[n] = LFCB[ind_LF][n];
- st1[n + 8] = HFCB[ind_HF][n];
- }
-
- // 3.4.7.2.2 Stage 2 SNS VQ decoding (d09r02_F2F)
- // already done earlier -> submodeMSB, Gind, LS_indA, LS_indB, idxA, idxB
- int16_t shape_j = (submodeMSB << 1) + submodeLSB;
- int16_t gain_i = Gind;
-
- int16_t y[16];
- int16_t z[16];
-
- switch (shape_j) {
- case 0:
- MPVQdeenum(10, 10, LS_indA, idxA, y);
- MPVQdeenum(6, 1, LS_indB, idxB, z);
- for (uint8_t n = 10; n <= 15; n++) {
- y[n] = z[n - 10];
- }
- break;
- case 1:
- MPVQdeenum(10, 10, LS_indA, idxA, y);
- for (uint8_t n = 10; n <= 15; n++) {
- y[n] = 0;
- }
- break;
- case 2:
- MPVQdeenum(16, 8, LS_indA, idxA, y);
- break;
- case 3:
- MPVQdeenum(16, 6, LS_indA, idxA, y);
- break;
- }
-
- double yNorm = 0;
- for (uint8_t n = 0; n < 16; n++) {
- // yNorm += y[n]*(y[n]*1.0);
- yNorm += y[n] * y[n];
- }
- yNorm = std::sqrt(yNorm);
- // Note: we skipped intermediate signal xq_shape_j and applied yNorm
- // directly together with G_gain_i_shape_j
-
- double G_gain_i_shape_j =
- sns_vq_far_adj_gains[gain_i]; // default initialization to avoid warnings
- switch (shape_j) {
- case 0:
- G_gain_i_shape_j = sns_vq_reg_adj_gains[gain_i];
- break;
- case 1:
- G_gain_i_shape_j = sns_vq_reg_lf_adj_gains[gain_i];
- break;
- case 2:
- G_gain_i_shape_j = sns_vq_near_adj_gains[gain_i];
- break;
- case 3:
- G_gain_i_shape_j = sns_vq_far_adj_gains[gain_i];
- break;
- }
- if (0.0 != yNorm) // do we have to make this even more robust???
- {
- G_gain_i_shape_j /= yNorm;
- }
-
- // Synthesis of the Quantized SNS scale factor vector
- double scfQ[16];
- for (uint8_t n = 0; n < 16; n++) {
- double factor = 0;
- for (uint8_t col = 0; col < 16; col++) {
- factor += y[col] * D[n][col];
- }
- scfQ[n] = st1[n] + G_gain_i_shape_j * factor;
- }
-
- // 3.4.7.3 SNS scale factors interpolation (d09r02_F2F)
- double scfQint[64];
- scfQint[0] = scfQ[0];
- scfQint[1] = scfQ[0];
- for (uint8_t n = 0; n <= 14; n++) {
- scfQint[4 * n + 2] = scfQ[n] + (1.0 / 8.0 * (scfQ[n + 1] - scfQ[n]));
- scfQint[4 * n + 3] = scfQ[n] + (3.0 / 8.0 * (scfQ[n + 1] - scfQ[n]));
- scfQint[4 * n + 4] = scfQ[n] + (5.0 / 8.0 * (scfQ[n + 1] - scfQ[n]));
- scfQint[4 * n + 5] = scfQ[n] + (7.0 / 8.0 * (scfQ[n + 1] - scfQ[n]));
- }
- scfQint[62] = scfQ[15] + 1 / 8.0 * (scfQ[15] - scfQ[14]);
- scfQint[63] = scfQ[15] + 3 / 8.0 * (scfQ[15] - scfQ[14]);
-
- // add special handling for lc3Config.N_b=60 (happens for 7.5ms and fs=8kHz)
- // see section 3.4.7.3 SNS scale factors interpolation (d1.0r03 including
- // Errata 15036)
- const uint8_t n2 = 64 - lc3Config.N_b;
- if (n2 != 0) {
- for (uint8_t i = 0; i < n2; i++) {
- scfQint[i] = (scfQint[2 * i] + scfQint[2 * i + 1]) / 2;
- }
- for (uint8_t i = n2; i < lc3Config.N_b; i++) {
- scfQint[i] = scfQint[i + n2];
- }
- }
-
- double g_SNS[64];
- for (uint8_t b = 0; b < lc3Config.N_b; b++) {
- g_SNS[b] = exp2(scfQint[b]);
- }
-
- // 3.4.7.4 Spectral Shaping (d09r02_F2F)
- // for (b=0; b<𝑁𝑏; b++)
- for (uint8_t b = 0; b < lc3Config.N_b; b++) {
- // for (k=𝐼𝑓𝑠 (𝑏); k< 𝐼𝑓𝑠 (𝑏 + 1); k++)
- for (uint16_t k = I_fs[b]; k < I_fs[b + 1]; k++) {
- //𝑋 ̂(𝑘) = 𝑋𝑆 ̂(𝑘) ∙ 𝑔𝑆𝑁𝑆 (𝑏)
- X_hat_ss[k] = X_s_tns[k] * g_SNS[b];
- }
- }
-}
-
-void SpectralNoiseShaping::registerDatapoints(DatapointContainer* datapoints) {}
-
-} // namespace Lc3Dec
diff --git a/system/embdrv/lc3_dec/Decoder/SpectralNoiseShaping.hpp b/system/embdrv/lc3_dec/Decoder/SpectralNoiseShaping.hpp
deleted file mode 100644
index 939e50367f..0000000000
--- a/system/embdrv/lc3_dec/Decoder/SpectralNoiseShaping.hpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * SpectralNoiseShaping.hpp
- *
- * 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.
- */
-
-#ifndef SPECTRAL_NOISE_SHAPING_H_
-#define SPECTRAL_NOISE_SHAPING_H_
-
-#include <cstdint>
-
-#include "Datapoints.hpp"
-#include "Lc3Config.hpp"
-
-namespace Lc3Dec {
-
-class SpectralNoiseShaping {
- public:
- SpectralNoiseShaping(const Lc3Config& lc3Config_);
-
- virtual ~SpectralNoiseShaping();
-
- void registerDatapoints(DatapointContainer* datapoints);
-
- void run(const double* const X_s_tns, double* const X_hat_ss, int16_t ind_LF,
- int16_t ind_HF, int16_t submodeMSB, int16_t submodeLSB, int16_t Gind,
- int16_t LS_indA, int16_t LS_indB, int32_t idxA, int16_t idxB);
-
- const Lc3Config& lc3Config;
-
- private:
- int* I_fs;
-};
-
-} // namespace Lc3Dec
-
-#endif // SPECTRAL_NOISE_SHAPING_H_
diff --git a/system/embdrv/lc3_dec/Readme.txt b/system/embdrv/lc3_dec/Readme.txt
deleted file mode 100644
index 859d9bb49c..0000000000
--- a/system/embdrv/lc3_dec/Readme.txt
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Readme.txt
- *
- * 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.
- */
-
-Contents
-========
- (1) Introduction
- (2) Directory Structure
- (3) Naming Conventions
- (4) General Code Structure
- (5) Test and Debug Support
-
-(1) Introduction
-================
-(derived from Bluetooth SIG LC3 specification dr09r06)
-The Low Complexity Communication Codec (LC3) is an efficient Bluetooth Audio Codec for use in
-audio profiles. This codec can encode speech and music at a variety of bitrates. The LC3 can
-be incorporated in any Bluetooth audio profile.
-
-The LC3 specification allows floating point and fixed point implementations as long as the
-resulting decoded audio signals are sufficiently close in quality. The given implementation
-exploits floating point operation in the majority of the code.
-
-To deliver satisfactory audio quality under all channel conditions, it is strongly recommended
-that some form of Packet Loss Concealment (PLC) should be implemented on the receiving ends of
-audio connections. The purpose of packet loss concealment is to conceal the effect of unavailable
-or corrupted frame data for decoding. The given code implements the example PLC algorithm provided
-in the informative Appendix B of the LC3 specification. Alternative PLC schemes are possible, but have
-to meet or exceed the performance of the given implementation.
-
-The initial implementation of this codec has been made in year 2019 in parallel to final
-improvements and extensions to the LC3 specification. The final implementation has been matched
-to the specification, however, references in the code to the specification are not adapted to
-the latest formal changes in the specification. Thus, the revision of the specification referenced
-is given with each reference, so that it should be possible to track the links to the specification.
-
-(2) Directory Structure
-=======================
- |- Api -> include files needed by calling application code
- |- Common | -> implementation needed by LC3 encoder and decoder
- | |-- KissFft -> source code of kissfft library used for fast transforms
- | |-- Tables -> tables as given in Section 3.7 "Tables and constants" (dr09r06)
- |- Decoder -> implementation of LC3 decoder (*.hpp and *.cpp)
- |- Encoder -> implementation of LC3 encoder (*.hpp and *.cpp)
- |- TestSupport -> interface and dummy/demo implementation of "datapoint" access
- for test and debug support
-
-(3) Naming Conventions and Coding Style
-=======================================
- Names of variables/objects have been chosen to be as close as possible
-to the naming within the LC3 specification. This applies not only to the
-selected wording, but also to the chosen case and concatenation of words.
- Thus, variable naming may appear somewhat unorthodox to a standard C/C++ developer
-and is not always consistent in style. Nevertheless, the close link to the specification
-document is considered most valuable so that this approach has been followed.
- The LC3 specification contains textual descriptions, equations, pseudo-code, tables
-and reference intermediate outputs. The naming of variables is not perfectly consistent,
-particularly in the case of names for intermediate outputs in relation to the
-specification text. Thus, there are situations where we had to select one name out of
-different options or had to choose different names for internal variables and
-"datapoints" provided for test and debug support.
-
- Some parts of the code are directly converted from pseudo-code given in
-the specification document. Changes compared to the specification are made only
-when supported by technical arguments. Again, the close link to the specification
-is considered most valuable. Note that this implies in some situations that code
-is not optimized in terms of computation effort, memory usage and/or clarity of its structure.
-
-Further Conventions:
- - indentation using 4 spaces; no TABS at all
- - directory, file and class names are camel-case starting with a capital letter
-
-
-(4) General Code Structure
-==========================
- The implementation is in C++ where object oriented programming is mainly used to
- formulate the relations of higher level modules/classes. The code of the lower level
- modules is syntactically C++, but the style is more like plain old procedural
- programming. The latter is mainly due to the goal of formulating the code very close
- to the specification - not only with respect to its overall behaviour but also with
- respect to the organization. This is particularly true for the modules depending
- heavily on converted pseudo-code from the LC3 specification.
-
- A brief overview on the main class relationships is summarized in the following
- basic diagrams.
-
- Encoder:
- --------
- Lc3Encoder : main API and handling of multi-channel sessions
- | |(1)------(1) Lc3Config : configuration instance
- |
- |(1)-------(lc3Config.Nc) EncoderTop : toplevel class for single channel session;
- | | dynamically reallocates EncoderFrame instance in case
- | | of bitrate changes
- | |
- | |--- holds all sub-modules directly that are not dependent
- | on variable bitrate;
- |
- |(1)-----(1) EncoderFrame : toplevel processing per frame and
- reallocation of sub-modules in case
- of bitrate changes
-
- Decoder:
- --------
- Lc3Decoder : main API and handling of multi-channel sessions
- | |(1)------(1) Lc3Config : configuration instance
- |
- |(1)-------(lc3Config.Nc) DecoderTop : toplevel class for single channel session;
- | | dynamically reallocates DecoderFrame instance in case
- | | of bitrate changes
- | |
- | |--- holds all sub-modules directly that are not dependent
- | on variable bitrate;
- |
- |(1)-----(1) DecoderFrame : toplevel processing per frame and
- reallocation of sub-modules in case
- of bitrate changes
-
-
-(5) Test and Debug Support
-==========================
-The development of the codec implementation has been strongly based on close match of
-intermediate values with specified reference values. To be able to access the proper
-values in a standardized manner a simple "datapoint" API has been created.
- Note: this API is not fully optimized for usage within in android but may be extended
-for this purpose in future.
- The given API can be found in "TestSupport/Datapoints.hpp" with a basic (mainly dummy) implementation
-given in "TestSupport/DatapointsAndroid.cpp".
- To use this API an instance of "DatapointContainer" has to be created and provided to the
-Lc3Encoder and Lc3Decoder constructors when needed. Note: that this is not intended for final releases
-due to the additional resources needed.
diff --git a/system/embdrv/lc3_dec/TestSupport/Datapoints.hpp b/system/embdrv/lc3_dec/TestSupport/Datapoints.hpp
deleted file mode 100644
index 5817c96a60..0000000000
--- a/system/embdrv/lc3_dec/TestSupport/Datapoints.hpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Datapoints.hpp
- *
- * 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.
- */
-
-#ifndef __DATAPOINTS_HPP_
-#define __DATAPOINTS_HPP_
-
-#include <cstdint>
-
-class Datapoint;
-class ContainerRealization;
-
-class DatapointContainer {
- public:
- DatapointContainer();
- virtual ~DatapointContainer();
-
- void addDatapoint(const char* label, void* pData, uint16_t sizeInBytes);
- void addDatapoint(const char* label, const void* pData, uint16_t sizeInBytes);
- void log(const char* label, const void* pData, uint16_t sizeInBytes);
-
- uint16_t getDatapointSize(const char* label);
- bool getDatapointValue(const char* label, void* pDataBuffer,
- uint16_t bufferSize);
- bool setDatapointValue(const char* label, const void* pDataBuffer,
- uint16_t bufferSize);
-
- private:
- void addDatapoint(const char* label, Datapoint* pDatapoint);
- ContainerRealization* m_pContainer;
-};
-
-#endif // __DATAPOINTS_HPP_
diff --git a/system/embdrv/lc3_dec/TestSupport/DatapointsAndroid.cpp b/system/embdrv/lc3_dec/TestSupport/DatapointsAndroid.cpp
deleted file mode 100644
index 2caa9628f2..0000000000
--- a/system/embdrv/lc3_dec/TestSupport/DatapointsAndroid.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * DatapointsDummy.cpp
- *
- * 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 <iomanip>
-#include <iostream>
-#include <sstream>
-
-#include "Datapoints.hpp"
-
-class ContainerRealization {};
-
-DatapointContainer::DatapointContainer() : m_pContainer(nullptr) {
- // nothing stored yet; we may integrate a complete datapoint container when
- // more debugging is needed in the android context
- (void)m_pContainer;
-}
-
-DatapointContainer::~DatapointContainer() {}
-
-void DatapointContainer::addDatapoint(const char* label,
- Datapoint* pDatapoint) {}
-
-void DatapointContainer::addDatapoint(const char* label, void* pData,
- uint16_t sizeInBytes) {}
-
-void DatapointContainer::addDatapoint(const char* label, const void* pData,
- uint16_t sizeInBytes) {}
-
-void DatapointContainer::log(const char* label, const void* pData,
- uint16_t sizeInBytes) {
- // Note: this is just a first simple step to demonstrate the possibilities we
- // have.
- // In this case the datapoint label its size in bytes and its content as
- // hex-byte-stream is send to the android LOG.
- const uint8_t* pByteData = reinterpret_cast<const uint8_t*>(pData);
- std::string valueAsHexString("0x");
- std::ostringstream vStream;
- vStream << "0x";
- for (uint16_t byteNr = 0; byteNr < sizeInBytes; byteNr++) {
- vStream << std::right << std::setw(2) << std::setfill('0') << std::hex
- << static_cast<int>(pByteData[byteNr]);
- }
- // TODO: uncomment for testing
- // LOG(INFO) << label << "[" << sizeInBytes << "]:" << vStream.str();
-}
-
-uint16_t DatapointContainer::getDatapointSize(const char* label) { return 0; }
-
-bool DatapointContainer::getDatapointValue(const char* label, void* pDataBuffer,
- uint16_t bufferSize) {
- return false;
-}
-
-bool DatapointContainer::setDatapointValue(const char* label,
- const void* pDataBuffer,
- uint16_t bufferSize) {
- return false;
-}
diff --git a/system/embdrv/lc3_dec/fuzzer/liblc3codec_decoder_fuzzer.cpp b/system/embdrv/lc3_dec/fuzzer/liblc3codec_decoder_fuzzer.cpp
deleted file mode 100644
index e453e6e8cb..0000000000
--- a/system/embdrv/lc3_dec/fuzzer/liblc3codec_decoder_fuzzer.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <fuzzer/FuzzedDataProvider.h>
-
-#include "../Api/Lc3Decoder.hpp"
-
-using FrameDuration = Lc3Config::FrameDuration;
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- FuzzedDataProvider fdp(data, size);
-
- uint16_t fs = fdp.PickValueInArray({8000, 16000, 24000, 32000, 44100, 48000});
- FrameDuration fd =
- fdp.PickValueInArray({FrameDuration::d10ms, FrameDuration::d7p5ms});
- uint8_t bfi = fdp.ConsumeIntegralInRange(0, 1);
- uint8_t bec_detect = fdp.ConsumeIntegralInRange(0, 1);
-
- uint16_t input_byte_count = fdp.ConsumeIntegralInRange(20, 400);
-
- if (fdp.remaining_bytes() < input_byte_count) {
- return 0;
- }
-
- std::vector<uint8_t> encoded_bytes(input_byte_count);
-
- fdp.ConsumeData(encoded_bytes.data(), encoded_bytes.size());
-
- uint16_t output_frame_count = Lc3Config(fs, fd, 1).NF;
- std::vector<uint16_t> decoded_data(output_frame_count * 2);
-
- Lc3Decoder decoder(fs, fd);
- decoder.run(encoded_bytes.data(), encoded_bytes.size(), bfi,
- (int16_t*)decoded_data.data(), output_frame_count, bec_detect, 0);
-
- return 0;
-} \ No newline at end of file
diff --git a/system/embdrv/lc3_dec/fuzzer/liblc3codec_encoder_fuzzer.cpp b/system/embdrv/lc3_dec/fuzzer/liblc3codec_encoder_fuzzer.cpp
deleted file mode 100644
index e1014f7ce0..0000000000
--- a/system/embdrv/lc3_dec/fuzzer/liblc3codec_encoder_fuzzer.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <fuzzer/FuzzedDataProvider.h>
-
-#include "../Api/Lc3Encoder.hpp"
-
-using FrameDuration = Lc3Config::FrameDuration;
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- FuzzedDataProvider fdp(data, size);
-
- uint16_t fs = fdp.PickValueInArray({8000, 16000, 24000, 32000, 44100, 48000});
- FrameDuration fd =
- fdp.PickValueInArray({FrameDuration::d10ms, FrameDuration::d7p5ms});
- uint16_t output_byte_count = fdp.ConsumeIntegralInRange(20, 400);
-
- Lc3Config config(fs, fd, 1);
- if (config.getErrorStatus() != Lc3Config::ERROR_FREE) {
- return 0;
- }
-
- uint16_t num_frames = config.NF * config.Nc;
-
- if (fdp.remaining_bytes() < num_frames * 2) {
- return 0;
- }
-
- std::vector<uint16_t> input_frames(num_frames);
-
- fdp.ConsumeData(input_frames.data(),
- input_frames.size() * 2 /* each frame is 2 bytes */);
-
- Lc3Encoder encoder(config);
-
- std::vector<uint8_t> output(output_byte_count);
- encoder.run((const int16_t*)input_frames.data(), output_byte_count,
- output.data());
- return 0;
-} \ No newline at end of file
diff --git a/system/gd/Android.bp b/system/gd/Android.bp
index cbb475f5fe..449639bb70 100644
--- a/system/gd/Android.bp
+++ b/system/gd/Android.bp
@@ -183,6 +183,7 @@ cc_defaults {
":BluetoothL2capSources",
":BluetoothMetricsSources",
":BluetoothNeighborSources",
+ ":BluetoothOsSources",
":BluetoothPacketSources",
":BluetoothShimSources",
":BluetoothSecuritySources",
@@ -354,6 +355,7 @@ cc_test {
":BluetoothHciUnitTestSources",
":BluetoothL2capUnitTestSources",
":BluetoothMetricsTestSources",
+ ":BluetoothOsTestSources",
":BluetoothPacketTestSources",
":BluetoothShimTestSources",
":BluetoothSecurityUnitTestSources",
diff --git a/system/gd/att/att_module.h b/system/gd/att/att_module.h
index a04993c8b3..1322394e6e 100644
--- a/system/gd/att/att_module.h
+++ b/system/gd/att/att_module.h
@@ -25,6 +25,9 @@ namespace att {
class AttModule : public bluetooth::Module {
public:
AttModule() = default;
+ AttModule(const AttModule&) = delete;
+ AttModule& operator=(const AttModule&) = delete;
+
~AttModule() = default;
static const ModuleFactory Factory;
@@ -41,7 +44,6 @@ class AttModule : public bluetooth::Module {
private:
struct impl;
std::unique_ptr<impl> pimpl_;
- DISALLOW_COPY_AND_ASSIGN(AttModule);
};
} // namespace att
diff --git a/system/gd/btaa/activity_attribution.h b/system/gd/btaa/activity_attribution.h
index e2861286d9..93f5549dd3 100644
--- a/system/gd/btaa/activity_attribution.h
+++ b/system/gd/btaa/activity_attribution.h
@@ -50,6 +50,9 @@ class ActivityAttributionCallback {
class ActivityAttribution : public bluetooth::Module {
public:
ActivityAttribution() = default;
+ ActivityAttribution(const ActivityAttribution&) = delete;
+ ActivityAttribution& operator=(const ActivityAttribution&) = delete;
+
~ActivityAttribution() = default;
void Capture(const hal::HciPacket& packet, hal::SnoopLogger::PacketType type);
@@ -71,8 +74,6 @@ class ActivityAttribution : public bluetooth::Module {
private:
struct impl;
std::unique_ptr<impl> pimpl_;
-
- DISALLOW_COPY_AND_ASSIGN(ActivityAttribution);
};
} // namespace activity_attribution
diff --git a/system/gd/cert/run b/system/gd/cert/run
index c15d621f86..a71e42671e 100755
--- a/system/gd/cert/run
+++ b/system/gd/cert/run
@@ -79,6 +79,7 @@ CERT_TEST_VENV=${ANDROID_BUILD_TOP}/out/dist/bluetooth_venv
OUT_TARGET="${ANDROID_BUILD_TOP}/out/target"
TEST_CONFIG="${ANDROID_BUILD_TOP}/packages/modules/Bluetooth/system/blueberry/tests/gd/host_config.yaml"
TEST_FILTER="--presubmit"
+TEST_RUNNER="blueberry/tests/gd/gd_test_runner.py"
CPP_BUILD_TARGET="bluetooth_stack_with_facade root-canal bluetooth_packets_python3"
RUST_BUILD_TARGET="bluetooth_with_facades root-canal bluetooth_packets_python3 bt_topshim_facade"
BUILD_TARGET=$CPP_BUILD_TARGET
@@ -89,6 +90,7 @@ NUM_REPETITIONS="1"
SKIP_SOONG_BUILD=false
USE_ASHMEM_VENV=true
VERBOSE_MODE=false
+DEVICE_TEST=false
## Verify devices connected and valid
DUT_SERIAL="DUT Not Set"
@@ -120,6 +122,9 @@ function parse_options {
echo -e " Makes use of ashmem as best as possible for targeted speed increases."
echo -e "${BLUE} --device${NOCOLOR}"
echo -e " Run the test on the 2 real devices."
+ echo -e "${BLUE} --sl4a${NOCOLOR}"
+ echo -e " Run GD Sl4A combination tests using the default gd_sl4a config."
+ echo -e " Please install the correct SL4A build to DUT manually before running tests."
echo -e "${BLUE} --rust${NOCOLOR}"
echo -e " Run the test using the rust implementation on the 2 real devices."
echo -e "${BLUE} --rhost${NOCOLOR}"
@@ -152,27 +157,8 @@ function parse_options {
shift # past argument
;;
--device)
+ DEVICE_TEST=true
TEST_CONFIG="${ANDROID_BUILD_TOP}/packages/modules/Bluetooth/system/blueberry/tests/gd/devices_config.yaml"
- RR="$(cat ${TEST_CONFIG}|grep \'CERT\\\|DUT\')"
- if [ "$RR" != "" ]; then
- DUT_SERIAL="$(menu-adb DUT)"
- DUT_ADB="adb -s ${DUT_SERIAL}"
- DUT_NAME="$(adb devices -l | grep -v "List of device" | grep ${DUT_SERIAL} | awk '{ print $6 }' | cut -d ':' -f 2)"
- CERT_SERIAL="$(menu-adb CERT)"
- CERT_ADB="adb -s ${CERT_SERIAL}"
- CERT_NAME="$(adb devices -l | grep -v "List of device" | grep ${CERT_SERIAL} | awk '{ print $6 }' | cut -d ':' -f 2)"
-
- if [ "${CERT_SERIAL}" == "${DUT_SERIAL}" ]; then
- echo
- echo -e "${RED}ERROR: CERT and DUT cannot be the same device, or you only have one device connected!${NOCOLOR}"
- echo
- exit 1
- fi
-
- ## Set android devices in config
- sed -i "s/'DUT'/'${DUT_SERIAL}'/g" ${TEST_CONFIG}
- sed -i "s/'CERT'/'${CERT_SERIAL}'/g" ${TEST_CONFIG}
- fi
shift # past argument
;;
# Repeat running the specified test cases by N times in one single setup
@@ -192,6 +178,7 @@ function parse_options {
BUILD_TARGET=$RUST_BUILD_TARGET
export RUST_BACKTRACE=1
TEST_CONFIG="${ANDROID_BUILD_TOP}/packages/modules/Bluetooth/system/blueberry/tests/gd/rust_devices_config.yaml"
+ DEVICE_TEST=true
shift # past argument
;;
--rhost)
@@ -200,6 +187,12 @@ function parse_options {
TEST_CONFIG="${ANDROID_BUILD_TOP}/packages/modules/Bluetooth/system/blueberry/tests/gd/rust_host_config.yaml"
shift # past argument
;;
+ --sl4a)
+ TEST_CONFIG="${ANDROID_BUILD_TOP}/packages/modules/Bluetooth/system/blueberry/tests/gd_sl4a/gd_sl4a_device_config.yaml"
+ TEST_RUNNER="blueberry/tests/gd_sl4a/gd_sl4a_test_runner.py"
+ DEVICE_TEST=true
+ shift # past argument
+ ;;
# This will log everything to both log file and stdout
--verbose)
VERBOSE_MODE=true
@@ -237,6 +230,31 @@ function parse_options {
}
+function select_devices {
+ if [ "$DEVICE_TEST" == true ] ; then
+ RR="$(cat ${TEST_CONFIG}|grep \'CERT\\\|DUT\')"
+ if [ "$RR" != "" ]; then
+ DUT_SERIAL="$(menu-adb DUT)"
+ DUT_ADB="adb -s ${DUT_SERIAL}"
+ DUT_NAME="$(adb devices -l | grep -v "List of device" | grep ${DUT_SERIAL} | awk '{ print $6 }' | cut -d ':' -f 2)"
+ CERT_SERIAL="$(menu-adb CERT)"
+ CERT_ADB="adb -s ${CERT_SERIAL}"
+ CERT_NAME="$(adb devices -l | grep -v "List of device" | grep ${CERT_SERIAL} | awk '{ print $6 }' | cut -d ':' -f 2)"
+
+ if [ "${CERT_SERIAL}" == "${DUT_SERIAL}" ]; then
+ echo
+ echo -e "${RED}ERROR: CERT and DUT cannot be the same device, or you only have one device connected!${NOCOLOR}"
+ echo
+ exit 1
+ fi
+
+ ## Set android devices in config
+ sed -i "s/'DUT'/'${DUT_SERIAL}'/g" ${TEST_CONFIG}
+ sed -i "s/'CERT'/'${CERT_SERIAL}'/g" ${TEST_CONFIG}
+ fi
+ fi
+}
+
function soong_build {
if [ "$CLEAN_VENV" == true ] ; then
$ANDROID_BUILD_TOP/build/soong/soong_ui.bash --build-mode --"modules-in-a-dir" --dir="${ANDROID_BUILD_TOP}/packages/modules/Bluetooth/system" dist $BUILD_TARGET -j20
@@ -410,7 +428,7 @@ function gotta_go_fast {
function run_tests {
for n in $(seq "${NUM_REPETITIONS}"); do
- $(echo "${CERT_TEST_VENV}/bin/python" "${CERT_TEST_VENV}/sources/blueberry/tests/gd/gd_test_runner.py" \
+ $(echo "${CERT_TEST_VENV}/bin/python" "${CERT_TEST_VENV}/sources/${TEST_RUNNER}" \
"-c ${TEST_CONFIG}" "${TEST_FILTER}")
done
@@ -475,6 +493,7 @@ function menu-adb() {
function main {
check_environment
parse_options $@
+ select_devices
if [[ "${SKIP_SOONG_BUILD}" != true ]] ; then
soong_build
fi
diff --git a/system/gd/cert/run_topshim b/system/gd/cert/run_topshim
index 50a01343df..a2c04848c4 100755
--- a/system/gd/cert/run_topshim
+++ b/system/gd/cert/run_topshim
@@ -20,7 +20,8 @@ import os
import argparse
TEST_SUITES = [
- "blueberry.tests.gd.rust.topshim.facade.adapter_test"
+ "blueberry.tests.gd.rust.topshim.facade.adapter_test",
+ "blueberry.tests.gd.rust.topshim.facade.suspend_test"
]
SOONG_UI_BASH = 'build/soong/soong_ui.bash'
@@ -135,7 +136,7 @@ def main():
if not all(test_results):
failures = [i for i, x in enumerate(test_results) if not x]
for index in failures:
- print('TEST FAILLED: ' + TEST_SUITES[index])
+ print('TEST FAILED: ' + TEST_SUITES[index])
sys.exit(0)
print('TEST PASSED ' + str(len(test_results)) + ' tests were run')
diff --git a/system/gd/common/callback_list.h b/system/gd/common/callback_list.h
index a3ad6b1f18..441a5fa3ef 100644
--- a/system/gd/common/callback_list.h
+++ b/system/gd/common/callback_list.h
@@ -68,6 +68,9 @@ class CallbackList<void(Args...)> : public base::internal::CallbackListBase<Call
public:
using CallbackType = CallbackWithHandler<void(Args...)>;
CallbackList() = default;
+ CallbackList(const CallbackList&) = delete;
+ CallbackList& operator=(const CallbackList&) = delete;
+
template <typename... RunArgs>
void Notify(RunArgs&&... args) {
auto it = this->GetIterator();
@@ -76,9 +79,6 @@ class CallbackList<void(Args...)> : public base::internal::CallbackListBase<Call
cb->handler->Post(base::Bind(cb->callback, args...));
}
}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(CallbackList);
};
} // namespace common
diff --git a/system/gd/common/contextual_callback.h b/system/gd/common/contextual_callback.h
index 539352945f..ba78ed6ba1 100644
--- a/system/gd/common/contextual_callback.h
+++ b/system/gd/common/contextual_callback.h
@@ -39,8 +39,8 @@ class ContextualOnceCallback<R(Args...)> {
: callback_(std::move(callback)), context_(context) {}
constexpr ContextualOnceCallback() = default;
-
- DISALLOW_COPY_AND_ASSIGN(ContextualOnceCallback);
+ ContextualOnceCallback(const ContextualOnceCallback&) = delete;
+ ContextualOnceCallback& operator=(const ContextualOnceCallback&) = delete;
ContextualOnceCallback(ContextualOnceCallback&&) noexcept = default;
ContextualOnceCallback& operator=(ContextualOnceCallback&&) noexcept = default;
diff --git a/system/gd/hal/snoop_logger.cc b/system/gd/hal/snoop_logger.cc
index f517c8e0e9..8de479a05f 100644
--- a/system/gd/hal/snoop_logger.cc
+++ b/system/gd/hal/snoop_logger.cc
@@ -67,15 +67,14 @@ constexpr SnoopLogger::FileHeaderType kBtSnoopFileHeader = {
// the relevant system property
constexpr size_t kDefaultBtSnoopMaxPacketsPerFile = 0xffff;
-// We want to use at most 256 KB memory for btsnooz log
-constexpr size_t kDefaultBtsnoozMaxMemoryUsageBytes = 256 * 1024;
// We restrict the maximum packet size to 150 bytes
constexpr size_t kDefaultBtSnoozMaxBytesPerPacket = 150;
constexpr size_t kDefaultBtSnoozMaxPayloadBytesPerPacket =
kDefaultBtSnoozMaxBytesPerPacket - sizeof(SnoopLogger::PacketHeaderType);
-// Calculate max number of packets based on max memory usage and max packet size
-constexpr size_t kDefaultBtSnoozMaxPacketsPerBuffer =
- kDefaultBtsnoozMaxMemoryUsageBytes / kDefaultBtSnoozMaxBytesPerPacket;
+
+using namespace std::chrono_literals;
+constexpr std::chrono::hours kBtSnoozLogLifeTime = 12h;
+constexpr std::chrono::hours kBtSnoozLogDeleteRepeatingAlarmInterval = 1h;
std::string get_btsnoop_log_path(std::string log_dir, bool filtered) {
if (filtered) {
@@ -107,6 +106,20 @@ void delete_btsnoop_files(const std::string& log_path) {
}
}
+void delete_old_btsnooz_files(const std::string& log_path, const std::chrono::milliseconds log_life_time) {
+ auto opt_created_ts = os::FileCreatedTime(log_path);
+ if (!opt_created_ts) return;
+
+ using namespace std::chrono;
+ auto created_tp = opt_created_ts.value();
+ auto current_tp = std::chrono::system_clock::now();
+
+ auto diff = duration_cast<milliseconds>(current_tp - created_tp);
+ if (diff >= log_life_time) {
+ delete_btsnoop_files(log_path);
+ }
+}
+
size_t get_btsnooz_packet_length_to_write(const HciPacket& packet, SnoopLogger::PacketType type) {
static const size_t kAclHeaderSize = 4;
static const size_t kL2capHeaderSize = 4;
@@ -172,11 +185,16 @@ SnoopLogger::SnoopLogger(
std::string snoop_log_path,
std::string snooz_log_path,
size_t max_packets_per_file,
- const std::string& btsnoop_mode)
+ size_t max_packets_per_buffer,
+ const std::string& btsnoop_mode,
+ const std::chrono::milliseconds snooz_log_life_time,
+ const std::chrono::milliseconds snooz_log_delete_alarm_interval)
: snoop_log_path_(std::move(snoop_log_path)),
snooz_log_path_(std::move(snooz_log_path)),
max_packets_per_file_(max_packets_per_file),
- btsnooz_buffer_(kDefaultBtSnoozMaxPacketsPerBuffer) {
+ btsnooz_buffer_(max_packets_per_buffer),
+ snooz_log_life_time_(snooz_log_life_time),
+ snooz_log_delete_alarm_interval_(snooz_log_delete_alarm_interval) {
if (false && btsnoop_mode == kBtSnoopLogModeFiltered) {
// TODO(b/163733538): implement filtered snoop log in GD, currently filtered == disabled
LOG_INFO("Filtered Snoop Logs enabled");
@@ -360,14 +378,20 @@ void SnoopLogger::Start() {
if (is_enabled_) {
OpenNextSnoopLogFile();
}
+ alarm_ = std::make_unique<os::RepeatingAlarm>(GetHandler());
+ alarm_->Schedule(
+ common::Bind(&delete_old_btsnooz_files, snooz_log_path_, snooz_log_life_time_), snooz_log_delete_alarm_interval_);
}
void SnoopLogger::Stop() {
std::lock_guard<std::recursive_mutex> lock(file_mutex_);
- LOG_DEBUG("Dumping btsnooz log data to %s", snooz_log_path_.c_str());
- DumpSnoozLogToFile(btsnooz_buffer_.Drain());
LOG_DEBUG("Closing btsnoop log data at %s", snoop_log_path_.c_str());
CloseCurrentSnoopLogFile();
+ // Cancel the alarm
+ alarm_->Cancel();
+ alarm_.reset();
+ // delete any existing snooz logs
+ delete_btsnoop_files(snooz_log_path_);
}
DumpsysDataFinisher SnoopLogger::GetDumpsysData(flatbuffers::FlatBufferBuilder* builder) const {
@@ -391,6 +415,16 @@ size_t SnoopLogger::GetMaxPacketsPerFile() {
return max_packets_per_file;
}
+size_t SnoopLogger::GetMaxPacketsPerBuffer() {
+ // We want to use at most 256 KB memory for btsnooz log for release builds
+ // and 512 KB memory for userdebug/eng builds
+ auto is_debuggable = os::GetSystemProperty(kIsDebuggableProperty);
+ size_t btsnooz_max_memory_usage_bytes =
+ ((is_debuggable.has_value() && common::StringTrim(is_debuggable.value()) == "1") ? 512 : 256) * 1024;
+ // Calculate max number of packets based on max memory usage and max packet size
+ return btsnooz_max_memory_usage_bytes / kDefaultBtSnoozMaxBytesPerPacket;
+}
+
std::string SnoopLogger::GetBtSnoopMode() {
// Default mode is DISABLED on user build.
// In userdebug/eng build, it can also be overwritten by modifying the global setting
@@ -421,7 +455,10 @@ const ModuleFactory SnoopLogger::Factory = ModuleFactory([]() {
os::ParameterProvider::SnoopLogFilePath(),
os::ParameterProvider::SnoozLogFilePath(),
GetMaxPacketsPerFile(),
- GetBtSnoopMode());
+ GetMaxPacketsPerBuffer(),
+ GetBtSnoopMode(),
+ kBtSnoozLogLifeTime,
+ kBtSnoozLogDeleteRepeatingAlarmInterval);
});
} // namespace hal
diff --git a/system/gd/hal/snoop_logger.h b/system/gd/hal/snoop_logger.h
index 22e88d8873..3ec96fb705 100644
--- a/system/gd/hal/snoop_logger.h
+++ b/system/gd/hal/snoop_logger.h
@@ -24,6 +24,7 @@
#include "common/circular_buffer.h"
#include "hal/hci_hal.h"
#include "module.h"
+#include "os/repeating_alarm.h"
namespace bluetooth {
namespace hal {
@@ -62,6 +63,8 @@ class SnoopLogger : public ::bluetooth::Module {
// Changes to this value is only effective after restarting Bluetooth
static size_t GetMaxPacketsPerFile();
+ static size_t GetMaxPacketsPerBuffer();
+
// Get snoop logger mode based on current system setup
// Changes to this values is only effective after restarting Bluetooth
static std::string GetBtSnoopMode();
@@ -96,7 +99,10 @@ class SnoopLogger : public ::bluetooth::Module {
std::string snoop_log_path,
std::string snooz_log_path,
size_t max_packets_per_file,
- const std::string& btsnoop_mode);
+ size_t max_packets_per_buffer,
+ const std::string& btsnoop_mode,
+ const std::chrono::milliseconds snooz_log_life_time,
+ const std::chrono::milliseconds snooz_log_delete_alarm_interval);
void CloseCurrentSnoopLogFile();
void OpenNextSnoopLogFile();
void DumpSnoozLogToFile(const std::vector<std::string>& data) const;
@@ -111,6 +117,9 @@ class SnoopLogger : public ::bluetooth::Module {
common::CircularBuffer<std::string> btsnooz_buffer_;
size_t packet_counter_ = 0;
mutable std::recursive_mutex file_mutex_;
+ std::unique_ptr<os::RepeatingAlarm> alarm_;
+ std::chrono::milliseconds snooz_log_life_time_;
+ std::chrono::milliseconds snooz_log_delete_alarm_interval_;
};
} // namespace hal
diff --git a/system/gd/hal/snoop_logger_test.cc b/system/gd/hal/snoop_logger_test.cc
index dcfe92d79b..f945cb5253 100644
--- a/system/gd/hal/snoop_logger_test.cc
+++ b/system/gd/hal/snoop_logger_test.cc
@@ -51,6 +51,7 @@ std::vector<uint8_t> kHfpAtNrec0 = {0x02, 0x02, 0x20, 0x13, 0x00, 0x0f, 0x00, 0x
using bluetooth::TestModuleRegistry;
using bluetooth::hal::SnoopLogger;
+using namespace std::chrono_literals;
// Expose protected constructor for test
class TestSnoopLoggerModule : public SnoopLogger {
@@ -60,14 +61,28 @@ class TestSnoopLoggerModule : public SnoopLogger {
std::string snooz_log_path,
size_t max_packets_per_file,
const std::string& btsnoop_mode)
- : SnoopLogger(std::move(snoop_log_path), std::move(snooz_log_path), max_packets_per_file, btsnoop_mode) {}
+ : SnoopLogger(
+ std::move(snoop_log_path),
+ std::move(snooz_log_path),
+ max_packets_per_file,
+ SnoopLogger::GetMaxPacketsPerBuffer(),
+ btsnoop_mode,
+ 20ms,
+ 5ms) {}
std::string ToString() const override {
return std::string("TestSnoopLoggerModule");
}
+
+ void CallGetDumpsysData(flatbuffers::FlatBufferBuilder* builder) {
+ GetDumpsysData(builder);
+ }
};
class SnoopLoggerModuleTest : public Test {
+ public:
+ flatbuffers::FlatBufferBuilder* builder_;
+
protected:
void SetUp() override {
temp_dir_ = std::filesystem::temp_directory_path();
@@ -75,6 +90,8 @@ class SnoopLoggerModuleTest : public Test {
temp_snoop_log_last_ = temp_dir_ / "btsnoop_hci.log.last";
temp_snooz_log_ = temp_dir_ / "btsnooz_hci.log";
temp_snooz_log_last_ = temp_dir_ / "btsnooz_hci.log.last";
+ builder_ = new flatbuffers::FlatBufferBuilder();
+
DeleteSnoopLogFiles();
ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_));
ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_));
@@ -84,6 +101,7 @@ class SnoopLoggerModuleTest : public Test {
void TearDown() override {
DeleteSnoopLogFiles();
+ delete builder_;
}
void DeleteSnoopLogFiles() {
@@ -133,7 +151,7 @@ TEST_F(SnoopLoggerModuleTest, disable_snoop_log_test) {
// Verify states after test
ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_));
ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_));
- ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_));
+ ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_));
}
TEST_F(SnoopLoggerModuleTest, capture_one_packet_test) {
@@ -163,16 +181,19 @@ TEST_F(SnoopLoggerModuleTest, capture_hci_cmd_btsnooz_test) {
test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_looger);
snoop_looger->Capture(kInformationRequest, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::CMD);
+ snoop_looger->CallGetDumpsysData(builder_);
+
+ ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_));
+ ASSERT_EQ(
+ std::filesystem::file_size(temp_snooz_log_),
+ sizeof(SnoopLogger::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + kInformationRequest.size());
test_registry.StopAll();
// Verify states after test
ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_));
ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_));
- ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_));
- ASSERT_EQ(
- std::filesystem::file_size(temp_snooz_log_),
- sizeof(SnoopLogger::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + kInformationRequest.size());
+ ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_));
}
TEST_F(SnoopLoggerModuleTest, capture_l2cap_signal_packet_btsnooz_test) {
@@ -183,16 +204,19 @@ TEST_F(SnoopLoggerModuleTest, capture_l2cap_signal_packet_btsnooz_test) {
test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_looger);
snoop_looger->Capture(kSdpConnectionRequest, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL);
+ snoop_looger->CallGetDumpsysData(builder_);
+
+ ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_));
+ ASSERT_EQ(
+ std::filesystem::file_size(temp_snooz_log_),
+ sizeof(SnoopLogger::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + kSdpConnectionRequest.size());
test_registry.StopAll();
// Verify states after test
ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_));
ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_));
- ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_));
- ASSERT_EQ(
- std::filesystem::file_size(temp_snooz_log_),
- sizeof(SnoopLogger::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + kSdpConnectionRequest.size());
+ ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_));
}
TEST_F(SnoopLoggerModuleTest, capture_l2cap_short_data_packet_btsnooz_test) {
@@ -203,16 +227,19 @@ TEST_F(SnoopLoggerModuleTest, capture_l2cap_short_data_packet_btsnooz_test) {
test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_looger);
snoop_looger->Capture(kAvdtpSuspend, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL);
+ snoop_looger->CallGetDumpsysData(builder_);
+
+ ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_));
+ ASSERT_EQ(
+ std::filesystem::file_size(temp_snooz_log_),
+ sizeof(SnoopLogger::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + kAvdtpSuspend.size());
test_registry.StopAll();
// Verify states after test
ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_));
ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_));
- ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_));
- ASSERT_EQ(
- std::filesystem::file_size(temp_snooz_log_),
- sizeof(SnoopLogger::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + kAvdtpSuspend.size());
+ ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_));
}
TEST_F(SnoopLoggerModuleTest, capture_l2cap_long_data_packet_btsnooz_test) {
@@ -223,16 +250,36 @@ TEST_F(SnoopLoggerModuleTest, capture_l2cap_long_data_packet_btsnooz_test) {
test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_looger);
snoop_looger->Capture(kHfpAtNrec0, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL);
+ snoop_looger->CallGetDumpsysData(builder_);
+
+ ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_));
+ ASSERT_EQ(
+ std::filesystem::file_size(temp_snooz_log_),
+ sizeof(SnoopLogger::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + 14);
test_registry.StopAll();
// Verify states after test
ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_));
ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_));
+ ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_));
+}
+
+TEST_F(SnoopLoggerModuleTest, delete_old_snooz_log_files) {
+ // Actual test
+ auto* snoop_looger = new TestSnoopLoggerModule(
+ temp_snoop_log_.string(), temp_snooz_log_.string(), 10, SnoopLogger::kBtSnoopLogModeDisabled);
+ TestModuleRegistry test_registry;
+ test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_looger);
+
+ std::filesystem::create_directories(temp_snooz_log_);
+
ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_));
- ASSERT_EQ(
- std::filesystem::file_size(temp_snooz_log_),
- sizeof(SnoopLogger::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + 14);
+ std::this_thread::sleep_for(10ms);
+ ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_));
+ std::this_thread::sleep_for(15ms);
+ ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_));
+ test_registry.StopAll();
}
TEST_F(SnoopLoggerModuleTest, rotate_file_at_new_session_test) {
diff --git a/system/gd/hci/acl_manager.h b/system/gd/hci/acl_manager.h
index 72426bdafa..9c008013bb 100644
--- a/system/gd/hci/acl_manager.h
+++ b/system/gd/hci/acl_manager.h
@@ -57,6 +57,9 @@ class AclManager : public Module {
public:
AclManager();
+ AclManager(const AclManager&) = delete;
+ AclManager& operator=(const AclManager&) = delete;
+
// NOTE: It is necessary to forward declare a default destructor that overrides the base class one, because
// "struct impl" is forwarded declared in .cc and compiler needs a concrete definition of "struct impl" when
// compiling AclManager's destructor. Hence we need to forward declare the destructor for AclManager to delay
@@ -148,8 +151,6 @@ private:
struct impl;
std::unique_ptr<impl> pimpl_;
-
- DISALLOW_COPY_AND_ASSIGN(AclManager);
};
} // namespace hci
diff --git a/system/gd/hci/acl_manager/acl_connection.h b/system/gd/hci/acl_manager/acl_connection.h
index c396b1833a..1347c8232a 100644
--- a/system/gd/hci/acl_manager/acl_connection.h
+++ b/system/gd/hci/acl_manager/acl_connection.h
@@ -28,6 +28,9 @@ namespace acl_manager {
class AclConnection {
public:
AclConnection() : queue_up_end_(nullptr), handle_(0){};
+ AclConnection(const AclConnection&) = delete;
+ AclConnection& operator=(const AclConnection&) = delete;
+
virtual ~AclConnection() = default;
uint16_t GetHandle() const {
@@ -47,7 +50,6 @@ class AclConnection {
AclConnection(QueueUpEnd* queue_up_end, uint16_t handle) : queue_up_end_(queue_up_end), handle_(handle) {}
QueueUpEnd* queue_up_end_;
uint16_t handle_;
- DISALLOW_COPY_AND_ASSIGN(AclConnection);
};
} // namespace acl_manager
diff --git a/system/gd/hci/acl_manager/classic_acl_connection.cc b/system/gd/hci/acl_manager/classic_acl_connection.cc
index 5fd5eaf866..f80dbffda8 100644
--- a/system/gd/hci/acl_manager/classic_acl_connection.cc
+++ b/system/gd/hci/acl_manager/classic_acl_connection.cc
@@ -353,7 +353,7 @@ ClassicAclConnection::ClassicAclConnection(std::shared_ptr<Queue> queue,
}
ClassicAclConnection::~ClassicAclConnection() {
- pimpl_->PutEventCallbacks();
+ if (pimpl_) pimpl_->PutEventCallbacks();
delete pimpl_;
}
diff --git a/system/gd/hci/acl_manager/classic_acl_connection.h b/system/gd/hci/acl_manager/classic_acl_connection.h
index 328cbb1eb4..6870114e06 100644
--- a/system/gd/hci/acl_manager/classic_acl_connection.h
+++ b/system/gd/hci/acl_manager/classic_acl_connection.h
@@ -33,6 +33,9 @@ class ClassicAclConnection : public AclConnection {
ClassicAclConnection();
ClassicAclConnection(std::shared_ptr<Queue> queue, AclConnectionInterface* acl_connection_interface, uint16_t handle,
Address address);
+ ClassicAclConnection(const ClassicAclConnection&) = delete;
+ ClassicAclConnection& operator=(const ClassicAclConnection&) = delete;
+
~ClassicAclConnection();
virtual Address GetAddress() const {
@@ -86,7 +89,6 @@ class ClassicAclConnection : public AclConnection {
private:
struct impl;
struct impl* pimpl_ = nullptr;
- DISALLOW_COPY_AND_ASSIGN(ClassicAclConnection);
};
} // namespace acl_manager
diff --git a/system/gd/hci/acl_manager/le_acl_connection.cc b/system/gd/hci/acl_manager/le_acl_connection.cc
index d57aab2db4..8763cee396 100644
--- a/system/gd/hci/acl_manager/le_acl_connection.cc
+++ b/system/gd/hci/acl_manager/le_acl_connection.cc
@@ -117,7 +117,7 @@ LeAclConnection::LeAclConnection(
}
LeAclConnection::~LeAclConnection() {
- pimpl_->PutEventCallbacks();
+ if (pimpl_) pimpl_->PutEventCallbacks();
delete pimpl_;
}
diff --git a/system/gd/hci/acl_manager/le_acl_connection.h b/system/gd/hci/acl_manager/le_acl_connection.h
index fd81111ba6..0fc14a9585 100644
--- a/system/gd/hci/acl_manager/le_acl_connection.h
+++ b/system/gd/hci/acl_manager/le_acl_connection.h
@@ -39,6 +39,9 @@ class LeAclConnection : public AclConnection {
AddressWithType local_address,
AddressWithType remote_address,
Role role);
+ LeAclConnection(const LeAclConnection&) = delete;
+ LeAclConnection& operator=(const LeAclConnection&) = delete;
+
~LeAclConnection();
virtual AddressWithType GetLocalAddress() const {
@@ -84,7 +87,6 @@ class LeAclConnection : public AclConnection {
AddressWithType local_address_;
AddressWithType remote_address_;
Role role_;
- DISALLOW_COPY_AND_ASSIGN(LeAclConnection);
};
} // namespace acl_manager
diff --git a/system/gd/hci/acl_manager/le_impl.h b/system/gd/hci/acl_manager/le_impl.h
index b666fbd705..599cd8b607 100644
--- a/system/gd/hci/acl_manager/le_impl.h
+++ b/system/gd/hci/acl_manager/le_impl.h
@@ -452,15 +452,6 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback {
address_with_type.ToConnectListAddressType(), address_with_type.GetAddress());
}
- void clear_connect_list() {
- if (!address_manager_registered) {
- le_address_manager_->Register(this);
- address_manager_registered = true;
- }
- pause_connection = true;
- le_address_manager_->ClearConnectList();
- }
-
void remove_device_from_connect_list(AddressWithType address_with_type) {
direct_connections_.erase(address_with_type);
register_with_address_manager();
@@ -468,6 +459,11 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback {
address_with_type.ToConnectListAddressType(), address_with_type.GetAddress());
}
+ void clear_connect_list() {
+ register_with_address_manager();
+ le_address_manager_->ClearConnectList();
+ }
+
void add_device_to_resolving_list(
AddressWithType address_with_type,
const std::array<uint8_t, 16>& peer_irk,
diff --git a/system/gd/hci/command_interface.h b/system/gd/hci/command_interface.h
index eba01dbe07..28fa6273f2 100644
--- a/system/gd/hci/command_interface.h
+++ b/system/gd/hci/command_interface.h
@@ -28,8 +28,10 @@ template <typename T>
class CommandInterface {
public:
CommandInterface() = default;
+ CommandInterface(const CommandInterface&) = delete;
+ CommandInterface& operator=(const CommandInterface&) = delete;
+
virtual ~CommandInterface() = default;
- DISALLOW_COPY_AND_ASSIGN(CommandInterface);
virtual void EnqueueCommand(std::unique_ptr<T> command,
common::ContextualOnceCallback<void(CommandCompleteView)> on_complete) = 0;
diff --git a/system/gd/hci/controller.h b/system/gd/hci/controller.h
index ea45aef729..573c695ad6 100644
--- a/system/gd/hci/controller.h
+++ b/system/gd/hci/controller.h
@@ -28,8 +28,10 @@ namespace hci {
class Controller : public Module {
public:
Controller();
+ Controller(const Controller&) = delete;
+ Controller& operator=(const Controller&) = delete;
+
virtual ~Controller();
- DISALLOW_COPY_AND_ASSIGN(Controller);
using CompletedAclPacketsCallback =
common::ContextualCallback<void(uint16_t /* handle */, uint16_t /* num_packets */)>;
diff --git a/system/gd/hci/hci_layer.h b/system/gd/hci/hci_layer.h
index 8ff74d3867..bde991508d 100644
--- a/system/gd/hci/hci_layer.h
+++ b/system/gd/hci/hci_layer.h
@@ -43,8 +43,10 @@ class HciLayer : public Module, public CommandInterface<CommandBuilder> {
// LINT.IfChange
public:
HciLayer();
+ HciLayer(const HciLayer&) = delete;
+ HciLayer& operator=(const HciLayer&) = delete;
+
virtual ~HciLayer();
- DISALLOW_COPY_AND_ASSIGN(HciLayer);
void EnqueueCommand(
std::unique_ptr<CommandBuilder> command,
diff --git a/system/gd/hci/le_advertising_manager.h b/system/gd/hci/le_advertising_manager.h
index 75040fbc1f..557b110d8d 100644
--- a/system/gd/hci/le_advertising_manager.h
+++ b/system/gd/hci/le_advertising_manager.h
@@ -102,6 +102,8 @@ class LeAdvertisingManager : public bluetooth::Module {
static constexpr uint16_t kLeMaximumFragmentLength = 251;
static constexpr FragmentPreference kFragment_preference = FragmentPreference::CONTROLLER_SHOULD_NOT;
LeAdvertisingManager();
+ LeAdvertisingManager(const LeAdvertisingManager&) = delete;
+ LeAdvertisingManager& operator=(const LeAdvertisingManager&) = delete;
size_t GetNumberOfAdvertisingInstances() const;
@@ -153,7 +155,6 @@ class LeAdvertisingManager : public bluetooth::Module {
os::Handler* handler);
struct impl;
std::unique_ptr<impl> pimpl_;
- DISALLOW_COPY_AND_ASSIGN(LeAdvertisingManager);
};
} // namespace hci
diff --git a/system/gd/hci/le_scanning_manager.h b/system/gd/hci/le_scanning_manager.h
index 8e58fb5cb0..2bc5180e8d 100644
--- a/system/gd/hci/le_scanning_manager.h
+++ b/system/gd/hci/le_scanning_manager.h
@@ -42,6 +42,8 @@ class LeScanningManager : public bluetooth::Module {
static constexpr uint8_t kNotPeriodicAdvertisement = 0x00;
static constexpr ScannerId kInvalidScannerId = 0xFF;
LeScanningManager();
+ LeScanningManager(const LeScanningManager&) = delete;
+ LeScanningManager& operator=(const LeScanningManager&) = delete;
virtual void RegisterScanner(const Uuid app_uuid);
@@ -92,7 +94,6 @@ class LeScanningManager : public bluetooth::Module {
private:
struct impl;
std::unique_ptr<impl> pimpl_;
- DISALLOW_COPY_AND_ASSIGN(LeScanningManager);
};
} // namespace hci
diff --git a/system/gd/hci/vendor_specific_event_manager.h b/system/gd/hci/vendor_specific_event_manager.h
index 7e0f3334dc..3dba563847 100644
--- a/system/gd/hci/vendor_specific_event_manager.h
+++ b/system/gd/hci/vendor_specific_event_manager.h
@@ -24,6 +24,8 @@ namespace hci {
class VendorSpecificEventManager : public bluetooth::Module {
public:
VendorSpecificEventManager();
+ VendorSpecificEventManager(const VendorSpecificEventManager&) = delete;
+ VendorSpecificEventManager& operator=(const VendorSpecificEventManager&) = delete;
void RegisterEventHandler(VseSubeventCode event, common::ContextualCallback<void(VendorSpecificEventView)> handler);
@@ -43,7 +45,6 @@ class VendorSpecificEventManager : public bluetooth::Module {
private:
struct impl;
std::unique_ptr<impl> pimpl_;
- DISALLOW_COPY_AND_ASSIGN(VendorSpecificEventManager);
};
} // namespace hci
diff --git a/system/gd/iso/iso_manager.h b/system/gd/iso/iso_manager.h
index d38405c4e8..b40d6f5175 100644
--- a/system/gd/iso/iso_manager.h
+++ b/system/gd/iso/iso_manager.h
@@ -37,6 +37,9 @@ using IsoDataCallback = common::ContextualCallback<void(std::unique_ptr<hci::Iso
*/
class IsoManager {
public:
+ IsoManager(const IsoManager&) = delete;
+ IsoManager& operator=(const IsoManager&) = delete;
+
friend class IsoModule;
void RegisterIsoEstablishedCallback(CisEstablishedCallback cb);
@@ -80,7 +83,6 @@ class IsoManager {
private:
os::Handler* iso_handler_ = nullptr;
internal::IsoManagerImpl* iso_manager_impl_;
- DISALLOW_COPY_AND_ASSIGN(IsoManager);
};
} // namespace iso
diff --git a/system/gd/iso/iso_module.h b/system/gd/iso/iso_module.h
index 6db880c109..d767620b31 100644
--- a/system/gd/iso/iso_module.h
+++ b/system/gd/iso/iso_module.h
@@ -26,6 +26,9 @@ namespace iso {
class IsoModule : public bluetooth::Module {
public:
IsoModule() = default;
+ IsoModule(const IsoModule&) = delete;
+ IsoModule& operator=(const IsoModule&) = delete;
+
~IsoModule() = default;
/**
@@ -47,7 +50,6 @@ class IsoModule : public bluetooth::Module {
private:
struct impl;
std::unique_ptr<impl> pimpl_;
- DISALLOW_COPY_AND_ASSIGN(IsoModule);
};
} // namespace iso
diff --git a/system/gd/l2cap/classic/dynamic_channel_manager.h b/system/gd/l2cap/classic/dynamic_channel_manager.h
index 66e3aeec58..ab240ff0d3 100644
--- a/system/gd/l2cap/classic/dynamic_channel_manager.h
+++ b/system/gd/l2cap/classic/dynamic_channel_manager.h
@@ -122,6 +122,9 @@ class DynamicChannelManager {
friend class L2capClassicModule;
+ DynamicChannelManager(const DynamicChannelManager&) = delete;
+ DynamicChannelManager& operator=(const DynamicChannelManager&) = delete;
+
virtual ~DynamicChannelManager() = default;
protected:
@@ -139,7 +142,6 @@ class DynamicChannelManager {
internal::DynamicChannelServiceManagerImpl* service_manager_ = nullptr;
internal::LinkManager* link_manager_ = nullptr;
os::Handler* l2cap_layer_handler_ = nullptr;
- DISALLOW_COPY_AND_ASSIGN(DynamicChannelManager);
};
} // namespace classic
diff --git a/system/gd/l2cap/classic/dynamic_channel_service.h b/system/gd/l2cap/classic/dynamic_channel_service.h
index f098db1a03..40ead1f6ad 100644
--- a/system/gd/l2cap/classic/dynamic_channel_service.h
+++ b/system/gd/l2cap/classic/dynamic_channel_service.h
@@ -32,6 +32,8 @@ class DynamicChannelServiceManagerImpl;
class DynamicChannelService {
public:
DynamicChannelService() = default;
+ DynamicChannelService(const DynamicChannelService&) = delete;
+ DynamicChannelService& operator=(const DynamicChannelService&) = delete;
using OnUnregisteredCallback = common::ContextualOnceCallback<void()>;
@@ -59,7 +61,6 @@ class DynamicChannelService {
Psm psm_ = kDefaultPsm;
internal::DynamicChannelServiceManagerImpl* manager_ = nullptr;
os::Handler* l2cap_layer_handler_;
- DISALLOW_COPY_AND_ASSIGN(DynamicChannelService);
};
} // namespace classic
diff --git a/system/gd/l2cap/classic/fixed_channel_manager.h b/system/gd/l2cap/classic/fixed_channel_manager.h
index a3285e7d3e..9c40bd1e54 100644
--- a/system/gd/l2cap/classic/fixed_channel_manager.h
+++ b/system/gd/l2cap/classic/fixed_channel_manager.h
@@ -129,6 +129,9 @@ class FixedChannelManager {
virtual bool RegisterService(Cid cid, OnRegistrationCompleteCallback on_registration_complete,
OnConnectionOpenCallback on_connection_open, os::Handler* handler);
+ FixedChannelManager(const FixedChannelManager&) = delete;
+ FixedChannelManager& operator=(const FixedChannelManager&) = delete;
+
virtual ~FixedChannelManager() = default;
friend class L2capClassicModule;
@@ -143,7 +146,6 @@ class FixedChannelManager {
internal::FixedChannelServiceManagerImpl* service_manager_ = nullptr;
internal::LinkManager* link_manager_ = nullptr;
os::Handler* l2cap_layer_handler_ = nullptr;
- DISALLOW_COPY_AND_ASSIGN(FixedChannelManager);
};
} // namespace classic
diff --git a/system/gd/l2cap/classic/fixed_channel_service.h b/system/gd/l2cap/classic/fixed_channel_service.h
index d5d213b62a..447d3a80bd 100644
--- a/system/gd/l2cap/classic/fixed_channel_service.h
+++ b/system/gd/l2cap/classic/fixed_channel_service.h
@@ -32,6 +32,8 @@ class FixedChannelServiceManagerImpl;
class FixedChannelService {
public:
FixedChannelService() = default;
+ FixedChannelService(const FixedChannelService&) = delete;
+ FixedChannelService& operator=(const FixedChannelService&) = delete;
using OnUnregisteredCallback = common::OnceCallback<void()>;
@@ -51,7 +53,6 @@ class FixedChannelService {
Cid cid_ = kInvalidCid;
internal::FixedChannelServiceManagerImpl* manager_ = nullptr;
os::Handler* l2cap_layer_handler_;
- DISALLOW_COPY_AND_ASSIGN(FixedChannelService);
};
} // namespace classic
diff --git a/system/gd/l2cap/classic/internal/fixed_channel_impl.h b/system/gd/l2cap/classic/internal/fixed_channel_impl.h
index 4c4e9f17fb..37efa1db84 100644
--- a/system/gd/l2cap/classic/internal/fixed_channel_impl.h
+++ b/system/gd/l2cap/classic/internal/fixed_channel_impl.h
@@ -35,6 +35,9 @@ class FixedChannelImpl : public l2cap::internal::ChannelImpl {
public:
FixedChannelImpl(Cid cid, Link* link, os::Handler* l2cap_handler);
+ FixedChannelImpl(const FixedChannelImpl&) = delete;
+ FixedChannelImpl& operator=(const FixedChannelImpl&) = delete;
+
virtual ~FixedChannelImpl() = default;
hci::Address GetDevice() const {
@@ -96,8 +99,6 @@ class FixedChannelImpl : public l2cap::internal::ChannelImpl {
static constexpr size_t kChannelQueueSize = 10;
common::BidiQueue<packet::PacketView<packet::kLittleEndian>, packet::BasePacketBuilder> channel_queue_{
kChannelQueueSize};
-
- DISALLOW_COPY_AND_ASSIGN(FixedChannelImpl);
};
} // namespace internal
diff --git a/system/gd/l2cap/classic/internal/link.h b/system/gd/l2cap/classic/internal/link.h
index a5b17a9dc8..2b61aaebf0 100644
--- a/system/gd/l2cap/classic/internal/link.h
+++ b/system/gd/l2cap/classic/internal/link.h
@@ -51,6 +51,9 @@ class Link : public l2cap::internal::ILink, public hci::acl_manager::ConnectionM
DynamicChannelServiceManagerImpl* dynamic_service_manager, FixedChannelServiceManagerImpl* fixed_service_manager,
LinkManager* link_manager);
+ Link(const Link&) = delete;
+ Link& operator=(const Link&) = delete;
+
hci::AddressWithType GetDevice() const override {
return {acl_connection_->GetAddress(), hci::AddressType::PUBLIC_DEVICE_ADDRESS};
}
@@ -234,7 +237,6 @@ class Link : public l2cap::internal::ILink, public hci::acl_manager::ConnectionM
bool has_requested_authentication_ = false;
std::list<EncryptionChangeListener> encryption_change_listener_;
std::atomic_int remaining_packets_to_be_sent_ = 0;
- DISALLOW_COPY_AND_ASSIGN(Link);
};
} // namespace internal
diff --git a/system/gd/l2cap/classic/internal/link_manager.h b/system/gd/l2cap/classic/internal/link_manager.h
index a81b0f5aad..4d327ea5bf 100644
--- a/system/gd/l2cap/classic/internal/link_manager.h
+++ b/system/gd/l2cap/classic/internal/link_manager.h
@@ -52,6 +52,9 @@ class LinkManager : public hci::acl_manager::ConnectionCallbacks {
acl_manager_->RegisterCallbacks(this, l2cap_handler_);
}
+ LinkManager(const LinkManager&) = delete;
+ LinkManager& operator=(const LinkManager&) = delete;
+
struct PendingFixedChannelConnection {
os::Handler* handler_;
FixedChannelManager::OnConnectionFailureCallback on_fail_callback_;
@@ -147,8 +150,6 @@ class LinkManager : public hci::acl_manager::ConnectionCallbacks {
os::Handler* link_property_callback_handler_ = nullptr;
std::unordered_set<hci::Address> disconnected_links_;
std::unordered_set<hci::Address> links_with_pending_packets_;
-
- DISALLOW_COPY_AND_ASSIGN(LinkManager);
};
} // namespace internal
diff --git a/system/gd/l2cap/classic/l2cap_classic_module.h b/system/gd/l2cap/classic/l2cap_classic_module.h
index f22f039768..407de38dc4 100644
--- a/system/gd/l2cap/classic/l2cap_classic_module.h
+++ b/system/gd/l2cap/classic/l2cap_classic_module.h
@@ -36,6 +36,9 @@ namespace classic {
class L2capClassicModule : public bluetooth::Module {
public:
L2capClassicModule();
+ L2capClassicModule(const L2capClassicModule&) = delete;
+ L2capClassicModule& operator=(const L2capClassicModule&) = delete;
+
virtual ~L2capClassicModule();
/**
@@ -86,8 +89,6 @@ class L2capClassicModule : public bluetooth::Module {
private:
struct impl;
std::unique_ptr<impl> pimpl_;
-
- DISALLOW_COPY_AND_ASSIGN(L2capClassicModule);
};
} // namespace classic
diff --git a/system/gd/l2cap/internal/dynamic_channel_impl.h b/system/gd/l2cap/internal/dynamic_channel_impl.h
index a012fff2de..4ae959f2e6 100644
--- a/system/gd/l2cap/internal/dynamic_channel_impl.h
+++ b/system/gd/l2cap/internal/dynamic_channel_impl.h
@@ -36,6 +36,9 @@ class DynamicChannelImpl : public l2cap::internal::ChannelImpl {
public:
DynamicChannelImpl(Psm psm, Cid cid, Cid remote_cid, l2cap::internal::ILink* link, os::Handler* l2cap_handler);
+ DynamicChannelImpl(const DynamicChannelImpl&) = delete;
+ DynamicChannelImpl& operator=(const DynamicChannelImpl&) = delete;
+
virtual ~DynamicChannelImpl() = default;
hci::AddressWithType GetDevice() const;
@@ -90,8 +93,6 @@ class DynamicChannelImpl : public l2cap::internal::ChannelImpl {
static constexpr size_t kChannelQueueSize = 5;
common::BidiQueue<packet::PacketView<packet::kLittleEndian>, packet::BasePacketBuilder> channel_queue_{
kChannelQueueSize};
-
- DISALLOW_COPY_AND_ASSIGN(DynamicChannelImpl);
};
} // namespace internal
diff --git a/system/gd/l2cap/le/dynamic_channel_manager.h b/system/gd/l2cap/le/dynamic_channel_manager.h
index e5334ef13e..2d1b24f069 100644
--- a/system/gd/l2cap/le/dynamic_channel_manager.h
+++ b/system/gd/l2cap/le/dynamic_channel_manager.h
@@ -40,6 +40,9 @@ class DynamicChannelServiceManagerImpl;
class DynamicChannelManager {
public:
+ DynamicChannelManager(const DynamicChannelManager&) = delete;
+ DynamicChannelManager& operator=(const DynamicChannelManager&) = delete;
+
enum class ConnectionResultCode {
SUCCESS = 0,
FAIL_NO_SERVICE_REGISTERED = 1, // No service is registered
@@ -138,7 +141,6 @@ class DynamicChannelManager {
internal::DynamicChannelServiceManagerImpl* service_manager_ = nullptr;
internal::LinkManager* link_manager_ = nullptr;
os::Handler* l2cap_layer_handler_ = nullptr;
- DISALLOW_COPY_AND_ASSIGN(DynamicChannelManager);
};
} // namespace le
diff --git a/system/gd/l2cap/le/dynamic_channel_service.h b/system/gd/l2cap/le/dynamic_channel_service.h
index 898c885eca..4294e59aea 100644
--- a/system/gd/l2cap/le/dynamic_channel_service.h
+++ b/system/gd/l2cap/le/dynamic_channel_service.h
@@ -32,6 +32,8 @@ class DynamicChannelServiceManagerImpl;
class DynamicChannelService {
public:
DynamicChannelService() = default;
+ DynamicChannelService(const DynamicChannelService&) = delete;
+ DynamicChannelService& operator=(const DynamicChannelService&) = delete;
using OnUnregisteredCallback = common::OnceCallback<void()>;
@@ -58,7 +60,6 @@ class DynamicChannelService {
Psm psm_ = kDefaultPsm;
internal::DynamicChannelServiceManagerImpl* manager_ = nullptr;
os::Handler* l2cap_layer_handler_;
- DISALLOW_COPY_AND_ASSIGN(DynamicChannelService);
};
} // namespace le
diff --git a/system/gd/l2cap/le/fixed_channel_manager.h b/system/gd/l2cap/le/fixed_channel_manager.h
index 1b059ac342..9bd2c70cd8 100644
--- a/system/gd/l2cap/le/fixed_channel_manager.h
+++ b/system/gd/l2cap/le/fixed_channel_manager.h
@@ -36,6 +36,9 @@ class FixedChannelServiceManagerImpl;
class FixedChannelManager {
public:
+ FixedChannelManager(const FixedChannelManager&) = delete;
+ FixedChannelManager& operator=(const FixedChannelManager&) = delete;
+
enum class ConnectionResultCode {
SUCCESS = 0,
FAIL_NO_SERVICE_REGISTERED = 1, // No service is registered
@@ -136,7 +139,6 @@ class FixedChannelManager {
internal::FixedChannelServiceManagerImpl* service_manager_ = nullptr;
internal::LinkManager* link_manager_ = nullptr;
os::Handler* l2cap_layer_handler_ = nullptr;
- DISALLOW_COPY_AND_ASSIGN(FixedChannelManager);
};
} // namespace le
diff --git a/system/gd/l2cap/le/fixed_channel_service.h b/system/gd/l2cap/le/fixed_channel_service.h
index 0c4556e230..7660e31ec5 100644
--- a/system/gd/l2cap/le/fixed_channel_service.h
+++ b/system/gd/l2cap/le/fixed_channel_service.h
@@ -32,6 +32,8 @@ class FixedChannelServiceManagerImpl;
class FixedChannelService {
public:
FixedChannelService() = default;
+ FixedChannelService(const FixedChannelService&) = delete;
+ FixedChannelService& operator=(const FixedChannelService&) = delete;
using OnUnregisteredCallback = common::OnceCallback<void()>;
@@ -51,7 +53,6 @@ class FixedChannelService {
Cid cid_ = kInvalidCid;
internal::FixedChannelServiceManagerImpl* manager_ = nullptr;
os::Handler* l2cap_layer_handler_;
- DISALLOW_COPY_AND_ASSIGN(FixedChannelService);
};
} // namespace le
diff --git a/system/gd/l2cap/le/internal/fixed_channel_impl.h b/system/gd/l2cap/le/internal/fixed_channel_impl.h
index d4fb3a3708..59a68add89 100644
--- a/system/gd/l2cap/le/internal/fixed_channel_impl.h
+++ b/system/gd/l2cap/le/internal/fixed_channel_impl.h
@@ -36,6 +36,9 @@ class FixedChannelImpl : public l2cap::internal::ChannelImpl {
public:
FixedChannelImpl(Cid cid, Link* link, os::Handler* l2cap_handler);
+ FixedChannelImpl(const FixedChannelImpl&) = delete;
+ FixedChannelImpl& operator=(const FixedChannelImpl&) = delete;
+
virtual ~FixedChannelImpl() = default;
hci::AddressWithType GetDevice() const {
@@ -98,8 +101,6 @@ class FixedChannelImpl : public l2cap::internal::ChannelImpl {
static constexpr size_t kChannelQueueSize = 10;
common::BidiQueue<packet::PacketView<packet::kLittleEndian>, packet::BasePacketBuilder> channel_queue_{
kChannelQueueSize};
-
- DISALLOW_COPY_AND_ASSIGN(FixedChannelImpl);
};
} // namespace internal
diff --git a/system/gd/l2cap/le/internal/link.h b/system/gd/l2cap/le/internal/link.h
index 518793eb32..a17ea33b6d 100644
--- a/system/gd/l2cap/le/internal/link.h
+++ b/system/gd/l2cap/le/internal/link.h
@@ -49,6 +49,9 @@ class Link : public l2cap::internal::ILink, public hci::acl_manager::LeConnectio
DynamicChannelServiceManagerImpl* dynamic_service_manager, FixedChannelServiceManagerImpl* fixed_service_manager,
LinkManager* link_manager);
+ Link(const Link&) = delete;
+ Link& operator=(const Link&) = delete;
+
~Link() = default;
inline hci::AddressWithType GetDevice() const override {
@@ -170,7 +173,6 @@ class Link : public l2cap::internal::ILink, public hci::acl_manager::LeConnectio
uint16_t update_request_latency_;
uint16_t update_request_supervision_timeout_;
std::atomic_int remaining_packets_to_be_sent_ = 0;
- DISALLOW_COPY_AND_ASSIGN(Link);
// Received connection update complete from ACL manager. SignalId is bound to a valid number when we need to send a
// response to remote. If SignalId is bound to an invalid number, we don't send a response to remote, because the
diff --git a/system/gd/l2cap/le/internal/link_manager.h b/system/gd/l2cap/le/internal/link_manager.h
index c6ec046ec4..836a3f6e8c 100644
--- a/system/gd/l2cap/le/internal/link_manager.h
+++ b/system/gd/l2cap/le/internal/link_manager.h
@@ -56,6 +56,9 @@ class LinkManager : public hci::acl_manager::LeConnectionCallbacks {
acl_manager_->RegisterLeCallbacks(this, l2cap_handler_);
}
+ LinkManager(const LinkManager&) = delete;
+ LinkManager& operator=(const LinkManager&) = delete;
+
struct PendingFixedChannelConnection {
os::Handler* handler_;
FixedChannelManager::OnConnectionFailureCallback on_fail_callback_;
@@ -116,8 +119,6 @@ class LinkManager : public hci::acl_manager::LeConnectionCallbacks {
LinkPropertyListener* link_property_listener_ = nullptr;
std::unordered_set<hci::AddressWithType> disconnected_links_;
std::unordered_set<hci::AddressWithType> links_with_pending_packets_;
-
- DISALLOW_COPY_AND_ASSIGN(LinkManager);
};
} // namespace internal
diff --git a/system/gd/l2cap/le/l2cap_le_module.h b/system/gd/l2cap/le/l2cap_le_module.h
index 05cabd21ff..28352c0c68 100644
--- a/system/gd/l2cap/le/l2cap_le_module.h
+++ b/system/gd/l2cap/le/l2cap_le_module.h
@@ -39,6 +39,9 @@ namespace le {
class L2capLeModule : public bluetooth::Module {
public:
L2capLeModule();
+ L2capLeModule(const L2capLeModule&) = delete;
+ L2capLeModule& operator=(const L2capLeModule&) = delete;
+
virtual ~L2capLeModule();
/**
@@ -81,8 +84,6 @@ class L2capLeModule : public bluetooth::Module {
* This is not synchronized.
*/
virtual void SetLinkPropertyListener(os::Handler* handler, LinkPropertyListener* listener);
-
- DISALLOW_COPY_AND_ASSIGN(L2capLeModule);
};
} // namespace le
diff --git a/system/gd/neighbor/connectability.h b/system/gd/neighbor/connectability.h
index eebf741104..00858059dd 100644
--- a/system/gd/neighbor/connectability.h
+++ b/system/gd/neighbor/connectability.h
@@ -29,6 +29,9 @@ class ConnectabilityModule : public bluetooth::Module {
bool IsConnectable() const;
ConnectabilityModule();
+ ConnectabilityModule(const ConnectabilityModule&) = delete;
+ ConnectabilityModule& operator=(const ConnectabilityModule&) = delete;
+
~ConnectabilityModule();
static const ModuleFactory Factory;
@@ -44,8 +47,6 @@ class ConnectabilityModule : public bluetooth::Module {
private:
struct impl;
std::unique_ptr<impl> pimpl_;
-
- DISALLOW_COPY_AND_ASSIGN(ConnectabilityModule);
};
} // namespace neighbor
diff --git a/system/gd/neighbor/discoverability.h b/system/gd/neighbor/discoverability.h
index cce4b87965..4c118c293e 100644
--- a/system/gd/neighbor/discoverability.h
+++ b/system/gd/neighbor/discoverability.h
@@ -35,6 +35,9 @@ class DiscoverabilityModule : public bluetooth::Module {
static const ModuleFactory Factory;
DiscoverabilityModule();
+ DiscoverabilityModule(const DiscoverabilityModule&) = delete;
+ DiscoverabilityModule& operator=(const DiscoverabilityModule&) = delete;
+
~DiscoverabilityModule();
protected:
@@ -48,8 +51,6 @@ class DiscoverabilityModule : public bluetooth::Module {
private:
struct impl;
std::unique_ptr<impl> pimpl_;
-
- DISALLOW_COPY_AND_ASSIGN(DiscoverabilityModule);
};
} // namespace neighbor
diff --git a/system/gd/neighbor/inquiry.h b/system/gd/neighbor/inquiry.h
index 1482af521a..5304be5327 100644
--- a/system/gd/neighbor/inquiry.h
+++ b/system/gd/neighbor/inquiry.h
@@ -67,6 +67,9 @@ class InquiryModule : public bluetooth::Module {
static const ModuleFactory Factory;
InquiryModule();
+ InquiryModule(const InquiryModule&) = delete;
+ InquiryModule& operator=(const InquiryModule&) = delete;
+
~InquiryModule();
protected:
@@ -80,8 +83,6 @@ class InquiryModule : public bluetooth::Module {
private:
struct impl;
std::unique_ptr<impl> pimpl_;
-
- DISALLOW_COPY_AND_ASSIGN(InquiryModule);
};
} // namespace neighbor
diff --git a/system/gd/neighbor/name.h b/system/gd/neighbor/name.h
index 233757ddd4..48d8eadd2a 100644
--- a/system/gd/neighbor/name.h
+++ b/system/gd/neighbor/name.h
@@ -45,6 +45,9 @@ class NameModule : public bluetooth::Module {
static const ModuleFactory Factory;
NameModule();
+ NameModule(const NameModule&) = delete;
+ NameModule& operator=(const NameModule&) = delete;
+
~NameModule();
protected:
@@ -58,8 +61,6 @@ class NameModule : public bluetooth::Module {
private:
struct impl;
std::unique_ptr<impl> pimpl_;
-
- DISALLOW_COPY_AND_ASSIGN(NameModule);
};
} // namespace neighbor
diff --git a/system/gd/neighbor/name_db.h b/system/gd/neighbor/name_db.h
index 1180cff9bb..5164f721dd 100644
--- a/system/gd/neighbor/name_db.h
+++ b/system/gd/neighbor/name_db.h
@@ -40,6 +40,9 @@ class NameDbModule : public bluetooth::Module {
static const ModuleFactory Factory;
NameDbModule();
+ NameDbModule(const NameDbModule&) = delete;
+ NameDbModule& operator=(const NameDbModule&) = delete;
+
~NameDbModule();
protected:
@@ -53,8 +56,6 @@ class NameDbModule : public bluetooth::Module {
private:
struct impl;
std::unique_ptr<impl> pimpl_;
-
- DISALLOW_COPY_AND_ASSIGN(NameDbModule);
};
} // namespace neighbor
diff --git a/system/gd/neighbor/page.h b/system/gd/neighbor/page.h
index 14c3ae606b..19c55b9b92 100644
--- a/system/gd/neighbor/page.h
+++ b/system/gd/neighbor/page.h
@@ -43,6 +43,9 @@ class PageModule : public bluetooth::Module {
static const ModuleFactory Factory;
PageModule();
+ PageModule(const PageModule&) = delete;
+ PageModule& operator=(const PageModule&) = delete;
+
~PageModule();
protected:
@@ -56,8 +59,6 @@ class PageModule : public bluetooth::Module {
private:
struct impl;
std::unique_ptr<impl> pimpl_;
-
- DISALLOW_COPY_AND_ASSIGN(PageModule);
};
} // namespace neighbor
diff --git a/system/gd/neighbor/scan.h b/system/gd/neighbor/scan.h
index e1699b4e05..6cea59595d 100644
--- a/system/gd/neighbor/scan.h
+++ b/system/gd/neighbor/scan.h
@@ -25,6 +25,9 @@ namespace neighbor {
class ScanModule : public bluetooth::Module {
public:
ScanModule();
+ ScanModule(const ScanModule&) = delete;
+ ScanModule& operator=(const ScanModule&) = delete;
+
~ScanModule();
void SetInquiryScan();
@@ -48,8 +51,6 @@ class ScanModule : public bluetooth::Module {
private:
struct impl;
std::unique_ptr<impl> pimpl_;
-
- DISALLOW_COPY_AND_ASSIGN(ScanModule);
};
} // namespace neighbor
diff --git a/system/gd/os/Android.bp b/system/gd/os/Android.bp
index fb4c50c2b9..b2916c58a8 100644
--- a/system/gd/os/Android.bp
+++ b/system/gd/os/Android.bp
@@ -8,6 +8,13 @@ package {
}
filegroup {
+ name: "BluetoothOsSources",
+ srcs: [
+ "handler.cc",
+ ],
+}
+
+filegroup {
name: "BluetoothOsSources_android",
srcs: [
"android/metrics.cc",
@@ -36,6 +43,13 @@ filegroup {
}
filegroup {
+ name: "BluetoothOsTestSources",
+ srcs: [
+ "handler_unittest.cc",
+ ],
+}
+
+filegroup {
name: "BluetoothOsTestSources_host",
srcs: [
"host/system_properties_test.cc",
@@ -48,7 +62,6 @@ filegroup {
srcs: [
"linux_generic/alarm.cc",
"linux_generic/files.cc",
- "linux_generic/handler.cc",
"linux_generic/reactor.cc",
"linux_generic/repeating_alarm.cc",
"linux_generic/reactive_semaphore.cc",
@@ -62,7 +75,6 @@ filegroup {
srcs: [
"linux_generic/alarm_unittest.cc",
"linux_generic/files_test.cc",
- "linux_generic/handler_unittest.cc",
"linux_generic/queue_unittest.cc",
"linux_generic/reactor_unittest.cc",
"linux_generic/repeating_alarm_unittest.cc",
diff --git a/system/gd/os/BUILD.gn b/system/gd/os/BUILD.gn
index 790da5ed6b..48337e14e8 100644
--- a/system/gd/os/BUILD.gn
+++ b/system/gd/os/BUILD.gn
@@ -27,9 +27,9 @@ source_set("BluetoothOsSources_linux") {
source_set("BluetoothOsSources_linux_generic") {
sources = [
+ "handler.cc",
"linux_generic/alarm.cc",
"linux_generic/files.cc",
- "linux_generic/handler.cc",
"linux_generic/reactive_semaphore.cc",
"linux_generic/reactor.cc",
"linux_generic/repeating_alarm.cc",
diff --git a/system/gd/os/alarm.h b/system/gd/os/alarm.h
index 773c36f4ac..4a689da48b 100644
--- a/system/gd/os/alarm.h
+++ b/system/gd/os/alarm.h
@@ -36,11 +36,12 @@ class Alarm {
// Create and register a single-shot alarm on a given handler
explicit Alarm(Handler* handler);
+ Alarm(const Alarm&) = delete;
+ Alarm& operator=(const Alarm&) = delete;
+
// Unregister this alarm from the thread and release resource
~Alarm();
- DISALLOW_COPY_AND_ASSIGN(Alarm);
-
// Schedule the alarm with given delay
void Schedule(common::OnceClosure task, std::chrono::milliseconds delay);
diff --git a/system/gd/os/files.h b/system/gd/os/files.h
index 5a6721b1ef..5802aa1e67 100644
--- a/system/gd/os/files.h
+++ b/system/gd/os/files.h
@@ -16,6 +16,7 @@
#pragma once
+#include <chrono>
#include <iterator>
#include <optional>
@@ -45,5 +46,9 @@ bool WriteToFile(const std::string& path, const std::string& data);
// Return true on success, false on failure (e.g. file not exist, failed to remove, etc)
bool RemoveFile(const std::string& path);
+// Returns created time_point of given file, return std::nullopt on failure
+std::optional<std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>> FileCreatedTime(
+ const std::string& path);
+
} // namespace os
} // namespace bluetooth \ No newline at end of file
diff --git a/system/gd/os/linux_generic/handler.cc b/system/gd/os/handler.cc
index 2f996f91e6..ff1ee8802c 100644
--- a/system/gd/os/linux_generic/handler.cc
+++ b/system/gd/os/handler.cc
@@ -16,9 +16,6 @@
#include "os/handler.h"
-#include <sys/eventfd.h>
-#include <unistd.h>
-
#include <cstring>
#include "common/bind.h"
@@ -27,19 +24,14 @@
#include "os/reactor.h"
#include "os/utils.h"
-#ifndef EFD_SEMAPHORE
-#define EFD_SEMAPHORE 1
-#endif
-
namespace bluetooth {
namespace os {
using common::OnceClosure;
-Handler::Handler(Thread* thread)
- : tasks_(new std::queue<OnceClosure>()), thread_(thread), fd_(eventfd(0, EFD_SEMAPHORE | EFD_NONBLOCK)) {
- ASSERT(fd_ != -1);
+Handler::Handler(Thread* thread) : tasks_(new std::queue<OnceClosure>()), thread_(thread) {
+ event_ = thread_->GetReactor()->NewEvent();
reactable_ = thread_->GetReactor()->Register(
- fd_, common::Bind(&Handler::handle_next_event, common::Unretained(this)), common::Closure());
+ event_->Id(), common::Bind(&Handler::handle_next_event, common::Unretained(this)), common::Closure());
}
Handler::~Handler() {
@@ -47,10 +39,7 @@ Handler::~Handler() {
std::lock_guard<std::mutex> lock(mutex_);
ASSERT_LOG(was_cleared(), "Handlers must be cleared before they are destroyed");
}
-
- int close_status;
- RUN_NO_INTR(close_status = close(fd_));
- ASSERT(close_status != -1);
+ event_->Close();
}
void Handler::Post(OnceClosure closure) {
@@ -62,9 +51,7 @@ void Handler::Post(OnceClosure closure) {
}
tasks_->emplace(std::move(closure));
}
- uint64_t val = 1;
- auto write_result = eventfd_write(fd_, val);
- ASSERT(write_result != -1);
+ event_->Notify();
}
void Handler::Clear() {
@@ -76,9 +63,7 @@ void Handler::Clear() {
}
delete tmp;
- uint64_t val;
- while (eventfd_read(fd_, &val) == 0) {
- }
+ event_->Clear();
thread_->GetReactor()->Unregister(reactable_);
reactable_ = nullptr;
@@ -93,13 +78,12 @@ void Handler::handle_next_event() {
common::OnceClosure closure;
{
std::lock_guard<std::mutex> lock(mutex_);
- uint64_t val = 0;
- auto read_result = eventfd_read(fd_, &val);
+ bool has_data = event_->Read();
if (was_cleared()) {
return;
}
- ASSERT_LOG(read_result != -1, "eventfd read error %d %s", errno, strerror(errno));
+ ASSERT_LOG(has_data, "Notified for work but no work available");
closure = std::move(tasks_->front());
tasks_->pop();
diff --git a/system/gd/os/handler.h b/system/gd/os/handler.h
index 9e530bc36e..1dabbde7ff 100644
--- a/system/gd/os/handler.h
+++ b/system/gd/os/handler.h
@@ -38,11 +38,12 @@ class Handler : public common::IPostableContext {
// Create and register a handler on given thread
explicit Handler(Thread* thread);
+ Handler(const Handler&) = delete;
+ Handler& operator=(const Handler&) = delete;
+
// Unregister this handler from the thread and release resource. Unhandled events will be discarded and not executed.
virtual ~Handler();
- DISALLOW_COPY_AND_ASSIGN(Handler);
-
// Enqueue a closure to the queue of this handler
virtual void Post(common::OnceClosure closure) override;
@@ -102,7 +103,7 @@ class Handler : public common::IPostableContext {
};
std::queue<common::OnceClosure>* tasks_;
Thread* thread_;
- int fd_;
+ std::unique_ptr<Reactor::Event> event_;
Reactor::Reactable* reactable_;
mutable std::mutex mutex_;
void handle_next_event();
diff --git a/system/gd/os/linux_generic/handler_unittest.cc b/system/gd/os/handler_unittest.cc
index cea030ef1d..b8c580f4c9 100644
--- a/system/gd/os/linux_generic/handler_unittest.cc
+++ b/system/gd/os/handler_unittest.cc
@@ -16,8 +16,6 @@
#include "os/handler.h"
-#include <sys/eventfd.h>
-
#include <future>
#include <thread>
diff --git a/system/gd/os/linux_generic/files.cc b/system/gd/os/linux_generic/files.cc
index bb018bf374..cf1a4aade8 100644
--- a/system/gd/os/linux_generic/files.cc
+++ b/system/gd/os/linux_generic/files.cc
@@ -195,5 +195,19 @@ bool RemoveFile(const std::string& path) {
return true;
}
+std::optional<std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>> FileCreatedTime(
+ const std::string& path) {
+ struct stat file_info;
+ if (stat(path.c_str(), &file_info) != 0) {
+ LOG_ERROR("unable to read '%s' file metadata, error: %s", path.c_str(), strerror(errno));
+ return std::nullopt;
+ }
+ using namespace std::chrono;
+ using namespace std::chrono_literals;
+ auto created_ts = file_info.st_ctim;
+ auto d = seconds{created_ts.tv_sec} + nanoseconds{created_ts.tv_nsec};
+ return time_point<system_clock>(duration_cast<system_clock::duration>(d));
+}
+
} // namespace os
} // namespace bluetooth \ No newline at end of file
diff --git a/system/gd/os/linux_generic/reactive_semaphore.h b/system/gd/os/linux_generic/reactive_semaphore.h
index 718666c69c..dd54b1a9dc 100644
--- a/system/gd/os/linux_generic/reactive_semaphore.h
+++ b/system/gd/os/linux_generic/reactive_semaphore.h
@@ -26,6 +26,10 @@ class ReactiveSemaphore {
public:
// Creates a new ReactiveSemaphore with an initial value of |value|.
explicit ReactiveSemaphore(unsigned int value);
+
+ ReactiveSemaphore(const ReactiveSemaphore&) = delete;
+ ReactiveSemaphore& operator=(const ReactiveSemaphore&) = delete;
+
~ReactiveSemaphore();
// Decrements the value of |fd_|, this will cause a crash if |fd_| unreadable.
void Decrease();
@@ -33,8 +37,6 @@ class ReactiveSemaphore {
void Increase();
int GetFd();
- DISALLOW_COPY_AND_ASSIGN(ReactiveSemaphore);
-
private:
int fd_;
};
diff --git a/system/gd/os/linux_generic/reactor.cc b/system/gd/os/linux_generic/reactor.cc
index 5722c61392..f0c7b1509e 100644
--- a/system/gd/os/linux_generic/reactor.cc
+++ b/system/gd/os/linux_generic/reactor.cc
@@ -41,6 +41,47 @@ namespace bluetooth {
namespace os {
using common::Closure;
+struct Reactor::Event::impl {
+ impl() {
+ fd_ = eventfd(0, EFD_SEMAPHORE | EFD_NONBLOCK);
+ ASSERT_LOG(fd_ != -1, "Unable to create nonblocking event file descriptor semaphore");
+ }
+ ~impl() {
+ ASSERT_LOG(fd_ != -1, "Unable to close a never-opened event file descriptor");
+ close(fd_);
+ fd_ = -1;
+ }
+ int fd_ = -1;
+};
+
+Reactor::Event::Event() : pimpl_(new impl()) {}
+Reactor::Event::~Event() {
+ delete pimpl_;
+}
+
+bool Reactor::Event::Read() {
+ uint64_t val = 0;
+ return eventfd_read(pimpl_->fd_, &val) == 0;
+}
+int Reactor::Event::Id() const {
+ return pimpl_->fd_;
+}
+void Reactor::Event::Clear() {
+ uint64_t val;
+ while (eventfd_read(pimpl_->fd_, &val) == 0) {
+ }
+}
+void Reactor::Event::Close() {
+ int close_status;
+ RUN_NO_INTR(close_status = close(pimpl_->fd_));
+ ASSERT(close_status != -1);
+}
+void Reactor::Event::Notify() {
+ uint64_t val = 1;
+ auto write_result = eventfd_write(pimpl_->fd_, val);
+ ASSERT(write_result != -1);
+}
+
class Reactor::Reactable {
public:
Reactable(int fd, Closure on_read_ready, Closure on_write_ready)
@@ -165,6 +206,10 @@ void Reactor::Stop() {
ASSERT(control != -1);
}
+std::unique_ptr<Reactor::Event> Reactor::NewEvent() const {
+ return std::make_unique<Reactor::Event>();
+}
+
Reactor::Reactable* Reactor::Register(int fd, Closure on_read_ready, Closure on_write_ready) {
uint32_t poll_event_type = 0;
if (!on_read_ready.is_null()) {
diff --git a/system/gd/os/reactor.h b/system/gd/os/reactor.h
index e61f4f5aec..c85625c339 100644
--- a/system/gd/os/reactor.h
+++ b/system/gd/os/reactor.h
@@ -22,6 +22,7 @@
#include <functional>
#include <future>
#include <list>
+#include <memory>
#include <mutex>
#include <thread>
@@ -43,11 +44,12 @@ class Reactor {
// Construct a reactor on the current thread
Reactor();
+ Reactor(const Reactor&) = delete;
+ Reactor& operator=(const Reactor&) = delete;
+
// Destruct this reactor and release its resources
~Reactor();
- DISALLOW_COPY_AND_ASSIGN(Reactor);
-
// Start the reactor. The current thread will be blocked until Stop() is invoked and handled.
void Run();
@@ -71,6 +73,23 @@ class Reactor {
// Modify the registration for a reactable with given reactable
void ModifyRegistration(Reactable* reactable, common::Closure on_read_ready, common::Closure on_write_ready);
+ class Event {
+ public:
+ Event();
+ ~Event();
+ bool Read();
+ int Id() const;
+ void Clear();
+ void Close();
+ void Notify();
+
+ private:
+ Event(const Event& handler) = default;
+ struct impl;
+ impl* pimpl_{nullptr};
+ };
+ std::unique_ptr<Reactor::Event> NewEvent() const;
+
private:
mutable std::mutex mutex_;
int epoll_fd_;
diff --git a/system/gd/os/repeating_alarm.h b/system/gd/os/repeating_alarm.h
index 6b37162cf1..b261b5e7fd 100644
--- a/system/gd/os/repeating_alarm.h
+++ b/system/gd/os/repeating_alarm.h
@@ -36,11 +36,12 @@ class RepeatingAlarm {
// Create and register a repeating alarm on a given handler
explicit RepeatingAlarm(Handler* handler);
+ RepeatingAlarm(const RepeatingAlarm&) = delete;
+ RepeatingAlarm& operator=(const RepeatingAlarm&) = delete;
+
// Unregister this alarm from the thread and release resource
~RepeatingAlarm();
- DISALLOW_COPY_AND_ASSIGN(RepeatingAlarm);
-
// Schedule a repeating alarm with given period
void Schedule(common::Closure task, std::chrono::milliseconds period);
diff --git a/system/gd/os/thread.h b/system/gd/os/thread.h
index d14d75ea21..4be792d3cc 100644
--- a/system/gd/os/thread.h
+++ b/system/gd/os/thread.h
@@ -43,11 +43,12 @@ class Thread {
// priority: priority for kernel scheduler
Thread(const std::string& name, Priority priority);
+ Thread(const Thread&) = delete;
+ Thread& operator=(const Thread&) = delete;
+
// Stop and destroy this thread
~Thread();
- DISALLOW_COPY_AND_ASSIGN(Thread);
-
// Stop this thread. Must be invoked from another thread. After this thread is stopped, it cannot be started again.
bool Stop();
diff --git a/system/gd/rust/facade/src/main.rs b/system/gd/rust/facade/src/main.rs
index 55cfb0ca8d..3ce456cdff 100644
--- a/system/gd/rust/facade/src/main.rs
+++ b/system/gd/rust/facade/src/main.rs
@@ -14,10 +14,7 @@ use futures::stream::StreamExt;
use grpcio::*;
use log::debug;
use nix::sys::signal;
-use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use std::sync::{Arc, Mutex};
-use tokio::io::AsyncWriteExt;
-use tokio::net::TcpStream;
use tokio::runtime::Runtime;
fn main() {
@@ -51,7 +48,6 @@ async fn async_main(rt: Arc<Runtime>, mut sigint: mpsc::UnboundedReceiver<()>) {
let root_server_port = value_t!(matches, "root-server-port", u16).unwrap();
let grpc_port = value_t!(matches, "grpc-port", u16).unwrap();
- let signal_port = value_t!(matches, "signal-port", u16).unwrap();
let rootcanal_port = value_t!(matches, "rootcanal-port", u16).ok();
let env = Arc::new(Environment::new(2));
let mut server = ServerBuilder::new(env)
@@ -66,17 +62,10 @@ async fn async_main(rt: Arc<Runtime>, mut sigint: mpsc::UnboundedReceiver<()>) {
.unwrap();
server.start();
- indicate_started(signal_port).await;
sigint.next().await;
block_on(server.shutdown()).unwrap();
}
-async fn indicate_started(signal_port: u16) {
- let address = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), signal_port);
- let mut stream = TcpStream::connect(address).await.unwrap();
- stream.shutdown().await.unwrap();
-}
-
// TODO: remove as this is a temporary nix-based hack to catch SIGINT
fn install_sigint() -> mpsc::UnboundedReceiver<()> {
let (tx, rx) = mpsc::unbounded();
diff --git a/system/gd/rust/facade_proto/build.rs b/system/gd/rust/facade_proto/build.rs
index 7c9bc4c40f..bb6bf46289 100644
--- a/system/gd/rust/facade_proto/build.rs
+++ b/system/gd/rust/facade_proto/build.rs
@@ -58,19 +58,21 @@ fn main() {
_ => (),
}
- // Proto root is //platform2/bt/gd
+ // Proto root is //platform2/bt/system
let proto_root = match env::var("PLATFORM_SUBDIR") {
- Ok(dir) => PathBuf::from(dir).join("bt/gd"),
- // Currently at //platform2/gd/rust/facade_proto
- Err(_) => PathBuf::from(env::current_dir().unwrap()).join("../..").canonicalize().unwrap(),
+ Ok(dir) => PathBuf::from(dir).join("bt/system"),
+ // Currently at //platform2/bt/system/gd/rust/facade_proto
+ Err(_) => {
+ PathBuf::from(env::current_dir().unwrap()).join("../../..").canonicalize().unwrap()
+ }
};
//
// Generate protobuf output
//
- let facade_dir = proto_root.join("facade");
+ let facade_dir = proto_root.join("blueberry/facade");
let proto_input_files = [facade_dir.join("common.proto")];
- let proto_include_dirs = [facade_dir];
+ let proto_include_dirs = [facade_dir.clone()];
protoc_rust::Codegen::new()
.out_dir(proto_out_dir.as_os_str().to_str().unwrap())
@@ -84,17 +86,13 @@ fn main() {
// Generate grpc output
//
let grpc_proto_input_files = [
- proto_root.join("hci/facade/hci_facade.proto"),
- proto_root.join("hci/facade/controller_facade.proto"),
- proto_root.join("hal/hal_facade.proto"),
- proto_root.join("facade/rootservice.proto"),
- ];
- let grpc_proto_include_dirs = [
- proto_root.join("hci/facade"),
- proto_root.join("hal"),
- proto_root.join("facade"),
- proto_root,
+ facade_dir.join("hci/hci_facade.proto"),
+ facade_dir.join("hci/controller_facade.proto"),
+ facade_dir.join("hal/hal_facade.proto"),
+ facade_dir.join("rootservice.proto"),
];
+ let grpc_proto_include_dirs =
+ [facade_dir.join("hci"), facade_dir.join("hal"), facade_dir, proto_root];
protoc_grpcio::compile_grpc_protos(
&grpc_proto_input_files,
diff --git a/system/gd/rust/linux/client/src/command_handler.rs b/system/gd/rust/linux/client/src/command_handler.rs
index f789eaa93b..9f9f280c85 100644
--- a/system/gd/rust/linux/client/src/command_handler.rs
+++ b/system/gd/rust/linux/client/src/command_handler.rs
@@ -85,7 +85,8 @@ fn build_commands() -> HashMap<String, CommandOption> {
String::from("adapter"),
CommandOption {
description: String::from(
- "Enable/Disable/Show default bluetooth adapter. (e.g. adapter enable)",
+ "Enable/Disable/Show default bluetooth adapter. (e.g. adapter enable)\n
+ Discoverable On/Off (e.g. adapter discoverable on)",
),
function_pointer: CommandHandler::cmd_adapter,
},
@@ -244,47 +245,84 @@ impl CommandHandler {
}
let default_adapter = self.context.lock().unwrap().default_adapter;
- enforce_arg_len(args, 1, "adapter <enable|disable|show>", || match &args[0][0..] {
- "enable" => {
- self.context.lock().unwrap().manager_dbus.start(default_adapter);
- }
- "disable" => {
- self.context.lock().unwrap().manager_dbus.stop(default_adapter);
- }
- "show" => {
- if !self.context.lock().unwrap().adapter_ready {
- self.adapter_not_ready();
- return;
+ enforce_arg_len(args, 1, "adapter <enable|disable|show|discoverable>", || {
+ match &args[0][0..] {
+ "enable" => {
+ self.context.lock().unwrap().manager_dbus.start(default_adapter);
+ }
+ "disable" => {
+ self.context.lock().unwrap().manager_dbus.stop(default_adapter);
}
+ "show" => {
+ if !self.context.lock().unwrap().adapter_ready {
+ self.adapter_not_ready();
+ return;
+ }
- let enabled = self.context.lock().unwrap().enabled;
- let address = match self.context.lock().unwrap().adapter_address.as_ref() {
- Some(x) => x.clone(),
- None => String::from(""),
- };
- let name = self.context.lock().unwrap().adapter_dbus.as_ref().unwrap().get_name();
- let uuids = self.context.lock().unwrap().adapter_dbus.as_ref().unwrap().get_uuids();
- let cod = self
- .context
- .lock()
- .unwrap()
- .adapter_dbus
- .as_ref()
- .unwrap()
- .get_bluetooth_class();
- print_info!("Address: {}", address);
- print_info!("Name: {}", name);
- print_info!("State: {}", if enabled { "enabled" } else { "disabled" });
- print_info!("Class: {:#06x}", cod);
- print_info!(
- "Uuids: {}",
- DisplayList(
- uuids.iter().map(|&x| UuidHelper::to_string(&x)).collect::<Vec<String>>()
- )
- );
- }
- _ => {
- println!("Invalid argument '{}'", args[0]);
+ let enabled = self.context.lock().unwrap().enabled;
+ let address = match self.context.lock().unwrap().adapter_address.as_ref() {
+ Some(x) => x.clone(),
+ None => String::from(""),
+ };
+ let context = self.context.lock().unwrap();
+ let adapter_dbus = context.adapter_dbus.as_ref().unwrap();
+ let name = adapter_dbus.get_name();
+ let uuids = adapter_dbus.get_uuids();
+ let is_discoverable = adapter_dbus.get_discoverable();
+ let cod = adapter_dbus.get_bluetooth_class();
+ let multi_adv_supported = adapter_dbus.is_multi_advertisement_supported();
+ let le_ext_adv_supported = adapter_dbus.is_le_extended_advertising_supported();
+ print_info!("Address: {}", address);
+ print_info!("Name: {}", name);
+ print_info!("State: {}", if enabled { "enabled" } else { "disabled" });
+ print_info!("Discoverable: {}", is_discoverable);
+ print_info!("Class: {:#06x}", cod);
+ print_info!("IsMultiAdvertisementSupported: {}", multi_adv_supported);
+ print_info!("IsLeExtendedAdvertisingSupported: {}", le_ext_adv_supported);
+ print_info!(
+ "Uuids: {}",
+ DisplayList(
+ uuids
+ .iter()
+ .map(|&x| UuidHelper::to_string(&x))
+ .collect::<Vec<String>>()
+ )
+ );
+ }
+ "discoverable" => match &args[1][0..] {
+ "on" => {
+ let discoverable = self
+ .context
+ .lock()
+ .unwrap()
+ .adapter_dbus
+ .as_ref()
+ .unwrap()
+ .set_discoverable(true, 60);
+ print_info!(
+ "Set discoverable for 60s: {}",
+ if discoverable { "succeeded" } else { "failed" }
+ );
+ }
+ "off" => {
+ let discoverable = self
+ .context
+ .lock()
+ .unwrap()
+ .adapter_dbus
+ .as_ref()
+ .unwrap()
+ .set_discoverable(false, 60);
+ print_info!(
+ "Turn discoverable off: {}",
+ if discoverable { "succeeded" } else { "failed" }
+ );
+ }
+ _ => println!("Invalid argument for adapter discoverable '{}'", args[1]),
+ },
+ _ => {
+ println!("Invalid argument '{}'", args[0]);
+ }
}
});
}
diff --git a/system/gd/rust/linux/client/src/dbus_iface.rs b/system/gd/rust/linux/client/src/dbus_iface.rs
index d3afcd0441..1a5c42a7b2 100644
--- a/system/gd/rust/linux/client/src/dbus_iface.rs
+++ b/system/gd/rust/linux/client/src/dbus_iface.rs
@@ -309,6 +309,22 @@ impl IBluetooth for BluetoothDBus {
self.client_proxy.method("SetBluetoothClass", (cod,))
}
+ fn get_discoverable(&self) -> bool {
+ self.client_proxy.method("GetDiscoverable", ())
+ }
+
+ fn set_discoverable(&self, mode: bool, duration: u32) -> bool {
+ self.client_proxy.method("SetDiscoverable", (mode, duration))
+ }
+
+ fn is_multi_advertisement_supported(&self) -> bool {
+ self.client_proxy.method("IsMultiAdvertisementSupported", ())
+ }
+
+ fn is_le_extended_advertising_supported(&self) -> bool {
+ self.client_proxy.method("IsLeExtendedAdvertisingSupported", ())
+ }
+
fn start_discovery(&self) -> bool {
self.client_proxy.method("StartDiscovery", ())
}
diff --git a/system/gd/rust/linux/service/src/iface_bluetooth.rs b/system/gd/rust/linux/service/src/iface_bluetooth.rs
index 005de3e656..c413bda632 100644
--- a/system/gd/rust/linux/service/src/iface_bluetooth.rs
+++ b/system/gd/rust/linux/service/src/iface_bluetooth.rs
@@ -130,6 +130,26 @@ impl IBluetooth for IBluetoothDBus {
true
}
+ #[dbus_method("GetDiscoverable")]
+ fn get_discoverable(&self) -> bool {
+ true
+ }
+
+ #[dbus_method("SetDiscoverable")]
+ fn set_discoverable(&self, mode: bool, duration: u32) -> bool {
+ true
+ }
+
+ #[dbus_method("IsMultiAdvertisementSupported")]
+ fn is_multi_advertisement_supported(&self) -> bool {
+ true
+ }
+
+ #[dbus_method("IsLeExtendedAdvertisingSupported")]
+ fn is_le_extended_advertising_supported(&self) -> bool {
+ true
+ }
+
#[dbus_method("StartDiscovery")]
fn start_discovery(&self) -> bool {
true
diff --git a/system/gd/rust/linux/stack/src/bluetooth.rs b/system/gd/rust/linux/stack/src/bluetooth.rs
index ee0578c958..c3b1d3218f 100644
--- a/system/gd/rust/linux/stack/src/bluetooth.rs
+++ b/system/gd/rust/linux/stack/src/bluetooth.rs
@@ -2,8 +2,8 @@
use bt_topshim::btif::{
BaseCallbacks, BaseCallbacksDispatcher, BluetoothInterface, BluetoothProperty, BtAclState,
- BtBondState, BtDiscoveryState, BtHciErrorCode, BtPinCode, BtPropertyType, BtSspVariant,
- BtState, BtStatus, BtTransport, RawAddress, Uuid, Uuid128Bit,
+ BtBondState, BtDiscoveryState, BtHciErrorCode, BtLocalLeFeatures, BtPinCode, BtPropertyType,
+ BtScanMode, BtSspVariant, BtState, BtStatus, BtTransport, RawAddress, Uuid, Uuid128Bit,
};
use bt_topshim::{
profiles::hid_host::{HHCallbacksDispatcher, HidHost},
@@ -25,6 +25,9 @@ use crate::bluetooth_media::{BluetoothMedia, IBluetoothMedia, MediaActions};
use crate::uuid::{Profile, UuidHelper};
use crate::{BluetoothCallbackType, Message, RPCProxy};
+const DEFAULT_DISCOVERY_TIMEOUT_MS: u64 = 12800;
+const MIN_ADV_INSTANCES_FOR_MULTI_ADV: u8 = 5;
+
/// Defines the adapter API.
pub trait IBluetooth {
/// Adds a callback from a client who wishes to observe adapter events.
@@ -67,6 +70,19 @@ pub trait IBluetooth {
/// Sets the bluetooth class.
fn set_bluetooth_class(&self, cod: u32) -> bool;
+ /// Returns whether the adapter is discoverable.
+ fn get_discoverable(&self) -> bool;
+
+ /// Sets discoverability. If discoverable, limits the duration with given value.
+ fn set_discoverable(&self, mode: bool, duration: u32) -> bool;
+
+ /// Returns whether multi-advertisement is supported.
+ /// A minimum number of 5 advertising instances is required for multi-advertisment support.
+ fn is_multi_advertisement_supported(&self) -> bool;
+
+ /// Returns whether LE extended advertising is supported.
+ fn is_le_extended_advertising_supported(&self) -> bool;
+
/// Starts BREDR Inquiry.
fn start_discovery(&self) -> bool;
@@ -243,6 +259,7 @@ pub struct Bluetooth {
state: BtState,
tx: Sender<Message>,
uuid_helper: UuidHelper,
+ is_connectable: bool,
}
impl Bluetooth {
@@ -269,6 +286,7 @@ impl Bluetooth {
state: BtState::Off,
tx,
uuid_helper: UuidHelper::new(),
+ is_connectable: false,
}
}
@@ -322,6 +340,29 @@ impl Bluetooth {
}
}
+ fn get_connectable(&self) -> bool {
+ match self.properties.get(&BtPropertyType::AdapterScanMode) {
+ Some(prop) => match prop {
+ BluetoothProperty::AdapterScanMode(mode) => match *mode {
+ BtScanMode::Connectable | BtScanMode::ConnectableDiscoverable => true,
+ _ => false,
+ },
+ _ => false,
+ },
+ _ => false,
+ }
+ }
+
+ fn set_connectable(&mut self, mode: bool) -> bool {
+ self.is_connectable = mode;
+ if mode && self.get_discoverable() {
+ return true;
+ }
+ self.intf.lock().unwrap().set_adapter_property(BluetoothProperty::AdapterScanMode(
+ if mode { BtScanMode::Connectable } else { BtScanMode::None_ },
+ )) == 0
+ }
+
pub(crate) fn callback_disconnected(&mut self, id: u32, cb_type: BluetoothCallbackType) {
match cb_type {
BluetoothCallbackType::Adapter => {
@@ -786,6 +827,59 @@ impl IBluetooth for Bluetooth {
self.intf.lock().unwrap().set_adapter_property(BluetoothProperty::ClassOfDevice(cod)) == 0
}
+ fn get_discoverable(&self) -> bool {
+ match self.properties.get(&BtPropertyType::AdapterScanMode) {
+ Some(prop) => match prop {
+ BluetoothProperty::AdapterScanMode(mode) => match mode {
+ BtScanMode::ConnectableDiscoverable => true,
+ _ => false,
+ },
+ _ => false,
+ },
+ _ => false,
+ }
+ }
+
+ fn set_discoverable(&self, mode: bool, duration: u32) -> bool {
+ self.intf
+ .lock()
+ .unwrap()
+ .set_adapter_property(BluetoothProperty::AdapterDiscoverableTimeout(duration));
+ self.intf.lock().unwrap().set_adapter_property(BluetoothProperty::AdapterScanMode(
+ if mode {
+ BtScanMode::ConnectableDiscoverable
+ } else {
+ if self.is_connectable {
+ BtScanMode::Connectable
+ } else {
+ BtScanMode::None_
+ }
+ },
+ )) == 0
+ }
+
+ fn is_multi_advertisement_supported(&self) -> bool {
+ match self.properties.get(&BtPropertyType::LocalLeFeatures) {
+ Some(prop) => match prop {
+ BluetoothProperty::LocalLeFeatures(llf) => {
+ llf.max_adv_instance >= MIN_ADV_INSTANCES_FOR_MULTI_ADV
+ }
+ _ => false,
+ },
+ _ => false,
+ }
+ }
+
+ fn is_le_extended_advertising_supported(&self) -> bool {
+ match self.properties.get(&BtPropertyType::LocalLeFeatures) {
+ Some(prop) => match prop {
+ BluetoothProperty::LocalLeFeatures(llf) => llf.le_extended_advertising_supported,
+ _ => false,
+ },
+ _ => false,
+ }
+ }
+
fn start_discovery(&self) -> bool {
self.intf.lock().unwrap().start_discovery() == 0
}
@@ -803,20 +897,11 @@ impl IBluetooth for Bluetooth {
return 0;
}
- match self.properties.get(&BtPropertyType::AdapterDiscoveryTimeout) {
- Some(variant) => match variant {
- BluetoothProperty::AdapterDiscoveryTimeout(timeout) => {
- let seconds: u64 = (*timeout).into();
- let elapsed = self.discovering_started.elapsed();
- if elapsed.as_secs() >= seconds {
- 0
- } else {
- seconds * 1000 - elapsed.as_millis() as u64
- }
- }
- _ => 0,
- },
- _ => 0,
+ let elapsed_ms = self.discovering_started.elapsed().as_millis() as u64;
+ if elapsed_ms >= DEFAULT_DISCOVERY_TIMEOUT_MS {
+ 0
+ } else {
+ DEFAULT_DISCOVERY_TIMEOUT_MS - elapsed_ms
}
}
diff --git a/system/gd/rust/linux/stack/src/lib.rs b/system/gd/rust/linux/stack/src/lib.rs
index 160363e88a..ad21e6e617 100644
--- a/system/gd/rust/linux/stack/src/lib.rs
+++ b/system/gd/rust/linux/stack/src/lib.rs
@@ -1,7 +1,7 @@
-//! Fluoride/GD Bluetooth stack.
+//! Floss Bluetooth stack.
//!
-//! This crate provides the API implementation of the Fluoride/GD Bluetooth stack, independent of
-//! any RPC projection.
+//! This crate provides the API implementation of the Fluoride/GD Bluetooth
+//! stack, independent of any RPC projection.
#[macro_use]
extern crate num_derive;
@@ -27,9 +27,6 @@ use bt_topshim::{
},
};
-/// Represents a Bluetooth address.
-// TODO: Add support for LE random addresses.
-
#[derive(Clone, Debug)]
pub enum BluetoothCallbackType {
Adapter,
diff --git a/system/gd/rust/topshim/facade/Android.bp b/system/gd/rust/topshim/facade/Android.bp
index c97cca8972..95648c71ea 100644
--- a/system/gd/rust/topshim/facade/Android.bp
+++ b/system/gd/rust/topshim/facade/Android.bp
@@ -45,7 +45,6 @@ rust_binary_host {
"libbt-sbc-encoder",
"libFraunhoferAAC",
"libg722codec",
- "liblc3codec",
"liblc3",
"libudrv-uipc",
"libbluetooth_gd", // Gabeldorsche
diff --git a/system/gd/rust/topshim/facade/src/adapter_service.rs b/system/gd/rust/topshim/facade/src/adapter_service.rs
index efd96eebd4..1243b07b16 100644
--- a/system/gd/rust/topshim/facade/src/adapter_service.rs
+++ b/system/gd/rust/topshim/facade/src/adapter_service.rs
@@ -3,6 +3,7 @@
use bt_topshim::btif;
use bt_topshim::btif::{BaseCallbacks, BaseCallbacksDispatcher, BluetoothInterface};
+use bt_topshim_facade_protobuf::empty::Empty;
use bt_topshim_facade_protobuf::facade::{
EventType, FetchEventsRequest, FetchEventsResponse, SetDiscoveryModeRequest,
SetDiscoveryModeResponse, ToggleStackRequest, ToggleStackResponse,
@@ -118,4 +119,11 @@ impl AdapterService for AdapterServiceImpl {
sink.success(SetDiscoveryModeResponse::default()).await.unwrap();
})
}
+
+ fn clear_event_filter(&mut self, ctx: RpcContext<'_>, _req: Empty, sink: UnarySink<Empty>) {
+ self.btif_intf.lock().unwrap().clear_event_filter();
+ ctx.spawn(async move {
+ sink.success(Empty::default()).await.unwrap();
+ })
+ }
}
diff --git a/system/gd/rust/topshim/gatt/gatt_ble_scanner_shim.cc b/system/gd/rust/topshim/gatt/gatt_ble_scanner_shim.cc
index 9b34b612ef..65cdb8456c 100644
--- a/system/gd/rust/topshim/gatt/gatt_ble_scanner_shim.cc
+++ b/system/gd/rust/topshim/gatt/gatt_ble_scanner_shim.cc
@@ -16,13 +16,20 @@
#include "gd/rust/topshim/gatt/gatt_ble_scanner_shim.h"
+#include <base/bind.h>
+#include <base/callback.h>
+
#include <algorithm>
#include <iterator>
+#include <memory>
#include <vector>
+#include "bind_helpers.h"
#include "gd/rust/topshim/common/utils.h"
+#include "include/hardware/bt_common_types.h"
#include "rust/cxx.h"
#include "src/profiles/gatt.rs.h"
+#include "types/bluetooth/uuid.h"
#include "types/raw_address.h"
namespace bluetooth {
@@ -31,12 +38,65 @@ namespace rust {
namespace rusty = ::bluetooth::topshim::rust;
-void BleScannerIntf::RegisterCallbacks() {
- // Register self as a callback handler. We will dispatch to Rust callbacks.
- scanner_intf_->RegisterCallbacks(this);
+namespace internal {
+ApcfCommand ConvertApcfFromRust(const RustApcfCommand& command) {
+ RawAddress address = rusty::CopyFromRustAddress(command.address);
+
+ // Copy vectors + arrays
+ std::vector<uint8_t> name, data, data_mask;
+ std::array<uint8_t, 16> irk;
+ std::copy(command.name.begin(), command.name.end(), std::back_inserter(name));
+ std::copy(command.data.begin(), command.data.end(), std::back_inserter(data));
+ std::copy(command.data_mask.begin(), command.data_mask.end(), std::back_inserter(data_mask));
+ std::copy(command.irk.begin(), command.irk.end(), std::begin(irk));
+
+ ApcfCommand converted = {
+ .type = command.type_,
+ .address = address,
+ .addr_type = command.addr_type,
+ .uuid = bluetooth::Uuid::From128BitBE(command.uuid.uu),
+ .uuid_mask = bluetooth::Uuid::From128BitBE(command.uuid_mask.uu),
+ .name = name,
+ .company = command.company,
+ .company_mask = command.company_mask,
+ .data = data,
+ .data_mask = data_mask,
+ .irk = irk,
+ };
+
+ return converted;
}
-// ScanningCallbacks overrides
+std::vector<ApcfCommand> ConvertApcfVec(const ::rust::Vec<RustApcfCommand>& rustvec) {
+ std::vector<ApcfCommand> converted;
+
+ for (const RustApcfCommand& command : rustvec) {
+ converted.push_back(ConvertApcfFromRust(command));
+ }
+
+ return converted;
+}
+
+::btgatt_filt_param_setup_t ConvertRustFilterParam(const RustGattFilterParam& param) {
+ ::btgatt_filt_param_setup_t converted = {
+ .feat_seln = param.feat_seln,
+ .list_logic_type = param.list_logic_type,
+ .filt_logic_type = param.filt_logic_type,
+ .rssi_high_thres = param.rssi_high_thres,
+ .rssi_low_thres = param.rssi_low_thres,
+ .dely_mode = param.delay_mode,
+ .found_timeout = param.found_timeout,
+ .lost_timeout = param.lost_timeout,
+ .found_timeout_cnt = param.found_timeout_count,
+ .num_of_tracking_entries = param.num_of_tracking_entries,
+ };
+
+ return converted;
+}
+} // namespace internal
+
+// ScanningCallbacks implementations
+
void BleScannerIntf::OnScannerRegistered(const bluetooth::Uuid app_uuid, uint8_t scannerId, uint8_t status) {
rusty::gdscan_on_scanner_registered(reinterpret_cast<const signed char*>(&app_uuid), scannerId, status);
}
@@ -89,8 +149,8 @@ void BleScannerIntf::OnTrackAdvFoundLost(AdvertisingTrackInfo ati) {
// .scan_response is copied below
};
- std::copy(ati.adv_packet.begin(), ati.adv_packet.end(), std::back_inserter(rust_info.adv_packet));
- std::copy(ati.scan_response.begin(), ati.scan_response.end(), std::back_inserter(rust_info.scan_response));
+ std::copy(rust_info.adv_packet.begin(), rust_info.adv_packet.end(), std::back_inserter(ati.adv_packet));
+ std::copy(rust_info.scan_response.begin(), rust_info.scan_response.end(), std::back_inserter(ati.scan_response));
rusty::gdscan_on_track_adv_found_lost(rust_info);
}
@@ -104,6 +164,185 @@ void BleScannerIntf::OnBatchScanThresholdCrossed(int client_if) {
rusty::gdscan_on_batch_scan_threshold_crossed(client_if);
}
+// BleScannerInterface implementations
+
+void BleScannerIntf::RegisterScanner(RustUuid uuid) {
+ bluetooth::Uuid converted = bluetooth::Uuid::From128BitBE(uuid.uu);
+ scanner_intf_->RegisterScanner(
+ converted, base::Bind(&BleScannerIntf::OnRegisterCallback, base::Unretained(this), uuid));
+}
+
+void BleScannerIntf::Unregister(uint8_t scanner_id) {
+ scanner_intf_->Unregister(scanner_id);
+}
+
+void BleScannerIntf::Scan(bool start) {
+ scanner_intf_->Scan(start);
+}
+
+void BleScannerIntf::ScanFilterParamSetup(
+ uint8_t scanner_id, uint8_t action, uint8_t filter_index, RustGattFilterParam filter_param) {
+ std::unique_ptr<::btgatt_filt_param_setup_t> converted =
+ std::make_unique<::btgatt_filt_param_setup_t>(std::move(internal::ConvertRustFilterParam(filter_param)));
+
+ scanner_intf_->ScanFilterParamSetup(
+ scanner_id,
+ action,
+ filter_index,
+ std::move(converted),
+ base::Bind(&BleScannerIntf::OnFilterParamSetupCallback, base::Unretained(this), scanner_id));
+}
+
+void BleScannerIntf::ScanFilterAdd(uint8_t filter_index, ::rust::Vec<RustApcfCommand> filters) {
+ auto converted = internal::ConvertApcfVec(filters);
+ scanner_intf_->ScanFilterAdd(
+ filter_index,
+ converted,
+ base::Bind(&BleScannerIntf::OnFilterConfigCallback, base::Unretained(this), filter_index));
+}
+
+void BleScannerIntf::ScanFilterClear(uint8_t filter_index) {
+ scanner_intf_->ScanFilterClear(
+ filter_index, base::Bind(&BleScannerIntf::OnFilterConfigCallback, base::Unretained(this), filter_index));
+}
+
+void BleScannerIntf::ScanFilterEnable(bool enable) {
+ scanner_intf_->ScanFilterEnable(enable, base::Bind(&BleScannerIntf::OnEnableCallback, base::Unretained(this)));
+}
+
+void BleScannerIntf::SetScanParameters(uint8_t scanner_id, uint16_t scan_interval, uint16_t scan_window) {
+ scanner_intf_->SetScanParameters(
+ scanner_id,
+ scan_interval,
+ scan_window,
+ base::Bind(&BleScannerIntf::OnStatusCallback, base::Unretained(this), scanner_id));
+}
+
+void BleScannerIntf::BatchscanConfigStorage(
+ uint8_t scanner_id,
+ int32_t batch_scan_full_max,
+ int32_t batch_scan_trunc_max,
+ int32_t batch_scan_notify_threshold) {
+ scanner_intf_->BatchscanConfigStorage(
+ scanner_id,
+ batch_scan_full_max,
+ batch_scan_trunc_max,
+ batch_scan_notify_threshold,
+ base::Bind(&BleScannerIntf::OnStatusCallback, base::Unretained(this), scanner_id));
+}
+
+void BleScannerIntf::BatchscanEnable(
+ int32_t scan_mode, uint16_t scan_interval, uint16_t scan_window, int32_t addr_type, int32_t discard_rule) {
+ scanner_intf_->BatchscanEnable(
+ scan_mode,
+ scan_interval,
+ scan_window,
+ addr_type,
+ discard_rule,
+ base::Bind(&BleScannerIntf::OnStatusCallback, base::Unretained(this), 0));
+}
+
+void BleScannerIntf::BatchscanDisable() {
+ scanner_intf_->BatchscanDisable(base::Bind(&BleScannerIntf::OnStatusCallback, base::Unretained(this), 0));
+}
+
+void BleScannerIntf::BatchscanReadReports(uint8_t scanner_id, int32_t scan_mode) {
+ scanner_intf_->BatchscanReadReports(scanner_id, scan_mode);
+}
+
+void BleScannerIntf::StartSync(uint8_t sid, RustRawAddress address, uint16_t skip, uint16_t timeout) {
+ RawAddress converted = rusty::CopyFromRustAddress(address);
+ scanner_intf_->StartSync(
+ sid,
+ converted,
+ skip,
+ timeout,
+ base::Bind(&BleScannerIntf::OnStartSyncCb, base::Unretained(this)),
+ base::Bind(&BleScannerIntf::OnSyncReportCb, base::Unretained(this)),
+ base::Bind(&BleScannerIntf::OnSyncLostCb, base::Unretained(this)));
+}
+
+void BleScannerIntf::StopSync(uint16_t handle) {
+ scanner_intf_->StopSync(handle);
+}
+
+void BleScannerIntf::CancelCreateSync(uint8_t sid, RustRawAddress address) {
+ RawAddress converted = rusty::CopyFromRustAddress(address);
+ scanner_intf_->CancelCreateSync(sid, converted);
+}
+
+void BleScannerIntf::TransferSync(RustRawAddress address, uint16_t service_data, uint16_t sync_handle) {
+ RawAddress converted = rusty::CopyFromRustAddress(address);
+ scanner_intf_->TransferSync(
+ converted, service_data, sync_handle, base::Bind(&BleScannerIntf::OnSyncTransferCb, base::Unretained(this)));
+}
+
+void BleScannerIntf::TransferSetInfo(RustRawAddress address, uint16_t service_data, uint8_t adv_handle) {
+ RawAddress converted = rusty::CopyFromRustAddress(address);
+ scanner_intf_->TransferSetInfo(
+ converted, service_data, adv_handle, base::Bind(&BleScannerIntf::OnSyncTransferCb, base::Unretained(this)));
+}
+
+void BleScannerIntf::SyncTxParameters(RustRawAddress address, uint8_t mode, uint16_t skip, uint16_t timeout) {
+ RawAddress converted = rusty::CopyFromRustAddress(address);
+ scanner_intf_->SyncTxParameters(
+ converted, mode, skip, timeout, base::Bind(&BleScannerIntf::OnStartSyncCb, base::Unretained(this)));
+}
+
+void BleScannerIntf::OnRegisterCallback(RustUuid uuid, uint8_t scanner_id, uint8_t btm_status) {
+ rusty::gdscan_register_callback(uuid, scanner_id, btm_status);
+}
+
+void BleScannerIntf::OnStatusCallback(uint8_t scanner_id, uint8_t btm_status) {
+ rusty::gdscan_status_callback(scanner_id, btm_status);
+}
+
+void BleScannerIntf::OnEnableCallback(uint8_t action, uint8_t btm_status) {
+ rusty::gdscan_enable_callback(action, btm_status);
+}
+
+void BleScannerIntf::OnFilterParamSetupCallback(
+ uint8_t scanner_id, uint8_t avbl_space, uint8_t action_type, uint8_t btm_status) {
+ rusty::gdscan_filter_param_setup_callback(scanner_id, avbl_space, action_type, btm_status);
+}
+
+void BleScannerIntf::OnFilterConfigCallback(
+ uint8_t filter_index, uint8_t filt_type, uint8_t avbl_space, uint8_t action, uint8_t btm_status) {
+ rusty::gdscan_filter_config_callback(filter_index, filt_type, avbl_space, action, btm_status);
+}
+
+void BleScannerIntf::OnStartSyncCb(
+ uint8_t status,
+ uint16_t sync_handle,
+ uint8_t advertising_sid,
+ uint8_t address_type,
+ RawAddress address,
+ uint8_t phy,
+ uint16_t interval) {
+ RustRawAddress converted = rusty::CopyToRustAddress(address);
+ rusty::gdscan_start_sync_callback(status, sync_handle, advertising_sid, address_type, &converted, phy, interval);
+}
+
+void BleScannerIntf::OnSyncReportCb(
+ uint16_t sync_handle, int8_t tx_power, int8_t rssi, uint8_t status, std::vector<uint8_t> data) {
+ rusty::gdscan_sync_report_callback(sync_handle, tx_power, rssi, status, data.data(), data.size());
+}
+
+void BleScannerIntf::OnSyncLostCb(uint16_t sync_handle) {
+ rusty::gdscan_sync_lost_callback(sync_handle);
+}
+
+void BleScannerIntf::OnSyncTransferCb(uint8_t status, RawAddress address) {
+ RustRawAddress converted = rusty::CopyToRustAddress(address);
+ rusty::gdscan_sync_transfer_callback(status, &converted);
+}
+
+void BleScannerIntf::RegisterCallbacks() {
+ // Register self as a callback handler. We will dispatch to Rust callbacks.
+ scanner_intf_->RegisterCallbacks(this);
+}
+
+// ScanningCallbacks overrides
std::unique_ptr<BleScannerIntf> GetBleScannerIntf(const unsigned char* gatt_intf) {
return std::make_unique<BleScannerIntf>(reinterpret_cast<const btgatt_interface_t*>(gatt_intf)->scanner);
}
diff --git a/system/gd/rust/topshim/gatt/gatt_ble_scanner_shim.h b/system/gd/rust/topshim/gatt/gatt_ble_scanner_shim.h
index eb89d12015..86fe902a62 100644
--- a/system/gd/rust/topshim/gatt/gatt_ble_scanner_shim.h
+++ b/system/gd/rust/topshim/gatt/gatt_ble_scanner_shim.h
@@ -26,13 +26,16 @@ namespace bluetooth {
namespace topshim {
namespace rust {
+struct RustApcfCommand;
+struct RustGattFilterParam;
+struct RustRawAddress;
+struct RustUuid;
+
class BleScannerIntf : public ScanningCallbacks {
public:
BleScannerIntf(BleScannerInterface* scanner_intf) : scanner_intf_(scanner_intf){};
~BleScannerIntf() = default;
- void RegisterCallbacks();
-
// ScanningCallbacks overrides
void OnScannerRegistered(const bluetooth::Uuid app_uuid, uint8_t scannerId, uint8_t status) override;
@@ -57,7 +60,106 @@ class BleScannerIntf : public ScanningCallbacks {
void OnBatchScanThresholdCrossed(int client_if) override;
+ // Implementations of BleScannerInterface. These don't inherit from
+ // BleScannerInterface because the Rust FFI boundary requires some clever
+ // modifications.
+
+ // Register a scanner for a Uuid. Response comes back via
+ // |OnRegisterCallback|.
+ void RegisterScanner(RustUuid uuid);
+
+ // Unregister a scanner with a |scanner_id|.
+ void Unregister(uint8_t scanner_id);
+
+ // Start/Stop LE scanning.
+ void Scan(bool start);
+
+ // Setup scan filter parameters. Get responses via
+ // |OnFilterParamSetupCallback|.
+ void ScanFilterParamSetup(uint8_t scanner_id, uint8_t action, uint8_t filter_index, RustGattFilterParam filter_param);
+
+ // Adds filters to given filter index. Gets responses via
+ // |OnFilterConfigCallback|.
+ void ScanFilterAdd(uint8_t filter_index, ::rust::Vec<RustApcfCommand> filters);
+
+ // Clear scan filter conditions for a specific index.
+ void ScanFilterClear(uint8_t filter_index);
+
+ // Enable/disable scan filter. Gets responses via |OnEnableCallback|.
+ void ScanFilterEnable(bool enable);
+
+ // Sets the LE scan interval and window in units of N * 0.625 msec. The result
+ // of this action is returned via |OnStatusCallback|.
+ void SetScanParameters(uint8_t scanner_id, uint16_t scan_interval, uint16_t scan_window);
+
+ // Configure the batchscan storage and get a response via |OnStatusCallback|.
+ void BatchscanConfigStorage(
+ uint8_t scanner_id,
+ int32_t batch_scan_full_max,
+ int32_t batch_scan_trunc_max,
+ int32_t batch_scan_notify_threshold);
+
+ // Enable batchscan. Gets responses via |OnStatusCallback| with scanner id
+ // = 0 (since multiple scanners can be registered).
+ void BatchscanEnable(
+ int32_t scan_mode, uint16_t scan_interval, uint16_t scan_window, int32_t addr_type, int32_t discard_rule);
+
+ // Disable batchscan. Gets responses via |OnStatusCallback| with a scanner id
+ // = 0 (since multiple scanners can be registered).
+ void BatchscanDisable();
+
+ // Read out batchscan report for a specific scanner. Gets responses via
+ // |ScanningCallbacks::OnBatchScanReports|.
+ void BatchscanReadReports(uint8_t scanner_id, int32_t scan_mode);
+
+ // Start periodic sync. Gets responses via |OnStartSyncCb|. Periodic reports
+ // come via |OnSyncReportCb| and |OnSyncLostCb|.
+ void StartSync(uint8_t sid, RustRawAddress address, uint16_t skip, uint16_t timeout);
+
+ // Stop periodic sync.
+ void StopSync(uint16_t handle);
+
+ // Cancel creating a periodic sync.
+ void CancelCreateSync(uint8_t sid, RustRawAddress address);
+
+ // Transfer sync data to target address. Gets responses via
+ // |OnSyncTransferCb|.
+ void TransferSync(RustRawAddress address, uint16_t service_data, uint16_t sync_handle);
+
+ // Transfer set info to target address. Gets responses via |OnSyncTransferCb|.
+ void TransferSetInfo(RustRawAddress address, uint16_t service_data, uint8_t adv_handle);
+
+ // Sync tx parameters to target address. Gets responses via |OnStartSyncCb|.
+ void SyncTxParameters(RustRawAddress address, uint8_t mode, uint16_t skip, uint16_t timeout);
+
+ // Register scanning callbacks to be dispatched to the Rust layer via static
+ // methods.
+ void RegisterCallbacks();
+
private:
+ // The callback functions below will get base::Bind to the apis that need it
+ // and will call the same Rust function with all the parameters. Some of these
+ // callbacks don't have all the parameters coming back in the original
+ // callback and will need the values to be base::Bind at the callsite.
+
+ void OnRegisterCallback(RustUuid uuid, uint8_t scanner_id, uint8_t btm_status);
+ void OnStatusCallback(uint8_t scanner_id, uint8_t btm_status);
+ void OnEnableCallback(uint8_t action, uint8_t btm_status);
+ void OnFilterParamSetupCallback(uint8_t scanner_id, uint8_t avbl_space, uint8_t action_type, uint8_t btm_status);
+ void OnFilterConfigCallback(
+ uint8_t filt_index, uint8_t filt_type, uint8_t avbl_space, uint8_t action, uint8_t btm_status);
+ void OnStartSyncCb(
+ uint8_t status,
+ uint16_t sync_handle,
+ uint8_t advertising_sid,
+ uint8_t address_type,
+ RawAddress address,
+ uint8_t phy,
+ uint16_t interval);
+ void OnSyncReportCb(uint16_t sync_handle, int8_t tx_power, int8_t rssi, uint8_t status, std::vector<uint8_t> data);
+ void OnSyncLostCb(uint16_t sync_handle);
+ void OnSyncTransferCb(uint8_t status, RawAddress address);
+
BleScannerInterface* scanner_intf_;
};
diff --git a/system/gd/rust/topshim/macros/src/lib.rs b/system/gd/rust/topshim/macros/src/lib.rs
index d042408f2e..3ae2a9d11f 100644
--- a/system/gd/rust/topshim/macros/src/lib.rs
+++ b/system/gd/rust/topshim/macros/src/lib.rs
@@ -73,22 +73,24 @@ impl Parse for CbVariant {
/// Implement C function to convert callback into enum variant.
///
/// Expected syntax:
+/// ```compile_fail
/// cb_variant(DispatcherType, function_name -> EnumType::Variant, args..., {
/// // Statements (maybe converting types)
/// // Args in order will be _0, _1, etc.
/// })
+/// ```
///
-/// args can do conversions inline as well. In order for conversions to work, the relevant
-/// From<T> trait should also be implemented.
+/// args can do conversions inline as well. In order for conversions to work, the relevant
+/// From<T> trait should also be implemented.
///
-/// Example:
-/// u32 -> BtStatus (requires impl From<u32> for BtStatus)
+/// Example:
+/// u32 -> BtStatus (requires impl From<u32> for BtStatus)
///
-/// To consume a value during conversion, you can use `Type -> _`. This is useful when you want
-/// to convert a pointer + size into a single Vec (i.e. using ptr_to_vec).
+/// To consume a value during conversion, you can use "Type -> _". This is useful when you want
+/// to convert a pointer + size into a single Vec (i.e. using ptr_to_vec).
///
-/// Example:
-/// u32 -> _
+/// Example:
+/// u32 -> _
pub fn cb_variant(input: TokenStream) -> TokenStream {
let parsed_cptr = parse_macro_input!(input as CbVariant);
diff --git a/system/gd/rust/topshim/src/btif.rs b/system/gd/rust/topshim/src/btif.rs
index dc7eaabdde..9febbaca3c 100644
--- a/system/gd/rust/topshim/src/btif.rs
+++ b/system/gd/rust/topshim/src/btif.rs
@@ -1,7 +1,6 @@
-//! Bluetooth interface shim
+//! Shim for `bt_interface_t`, providing access to libbluetooth.
//!
//! This is a shim interface for calling the C++ bluetooth interface via Rust.
-//!
use crate::bindings::root as bindings;
use crate::topstack::get_dispatchers;
@@ -135,7 +134,7 @@ pub enum BtPropertyType {
ServiceRecord,
AdapterScanMode,
AdapterBondedDevices,
- AdapterDiscoveryTimeout,
+ AdapterDiscoverableTimeout,
RemoteFriendlyName,
RemoteRssi,
RemoteVersionInfo,
@@ -300,7 +299,7 @@ pub enum BluetoothProperty {
ServiceRecord(BtServiceRecord),
AdapterScanMode(BtScanMode),
AdapterBondedDevices(Vec<RawAddress>),
- AdapterDiscoveryTimeout(u32),
+ AdapterDiscoverableTimeout(u32),
RemoteFriendlyName(String),
RemoteRssi(i8),
RemoteVersionInfo(BtRemoteVersion),
@@ -328,8 +327,8 @@ impl BluetoothProperty {
BluetoothProperty::ServiceRecord(_) => BtPropertyType::ServiceRecord,
BluetoothProperty::AdapterScanMode(_) => BtPropertyType::AdapterScanMode,
BluetoothProperty::AdapterBondedDevices(_) => BtPropertyType::AdapterBondedDevices,
- BluetoothProperty::AdapterDiscoveryTimeout(_) => {
- BtPropertyType::AdapterDiscoveryTimeout
+ BluetoothProperty::AdapterDiscoverableTimeout(_) => {
+ BtPropertyType::AdapterDiscoverableTimeout
}
BluetoothProperty::RemoteFriendlyName(_) => BtPropertyType::RemoteFriendlyName,
BluetoothProperty::RemoteRssi(_) => BtPropertyType::RemoteRssi,
@@ -357,7 +356,7 @@ impl BluetoothProperty {
BluetoothProperty::AdapterBondedDevices(devlist) => {
devlist.len() * mem::size_of::<RawAddress>()
}
- BluetoothProperty::AdapterDiscoveryTimeout(_) => mem::size_of::<u32>(),
+ BluetoothProperty::AdapterDiscoverableTimeout(_) => mem::size_of::<u32>(),
BluetoothProperty::RemoteFriendlyName(name) => {
cmp::min(PROPERTY_NAME_MAX, name.len() + 1)
}
@@ -374,10 +373,10 @@ impl BluetoothProperty {
}
}
- // Given a mutable array, this will copy the data to that array and return a
- // pointer to it.
- //
- // The lifetime of the returned pointer is tied to that of the slice given.
+ /// Given a mutable array, this will copy the data to that array and return a
+ /// pointer to it.
+ ///
+ /// The lifetime of the returned pointer is tied to that of the slice given.
fn get_data_ptr<'a>(&'a self, data: &'a mut [u8]) -> *mut u8 {
let len = self.get_len();
match &*self {
@@ -424,7 +423,7 @@ impl BluetoothProperty {
data[start..end].copy_from_slice(&dev.val);
}
}
- BluetoothProperty::AdapterDiscoveryTimeout(timeout) => {
+ BluetoothProperty::AdapterDiscoverableTimeout(timeout) => {
data.copy_from_slice(&timeout.to_ne_bytes());
}
BluetoothProperty::RemoteFriendlyName(name) => {
@@ -498,8 +497,8 @@ impl From<bindings::bt_property_t> for BluetoothProperty {
count,
))
}
- BtPropertyType::AdapterDiscoveryTimeout => {
- BluetoothProperty::AdapterDiscoveryTimeout(u32_from_bytes(slice))
+ BtPropertyType::AdapterDiscoverableTimeout => {
+ BluetoothProperty::AdapterDiscoverableTimeout(u32_from_bytes(slice))
}
BtPropertyType::RemoteFriendlyName => {
BluetoothProperty::RemoteFriendlyName(ascii_to_string(slice, len))
@@ -685,6 +684,7 @@ macro_rules! cast_to_const_ffi_address {
};
}
+/// An enum representing `bt_callbacks_t` from btif.
#[derive(Clone, Debug)]
pub enum BaseCallbacks {
AdapterState(BtState),
@@ -761,13 +761,14 @@ struct RawInterfaceWrapper {
unsafe impl Send for RawInterfaceWrapper {}
-pub struct BluetoothInterface {
- internal: RawInterfaceWrapper,
- pub is_init: bool,
- // Need to take ownership of callbacks so it doesn't get freed after init
- callbacks: Option<Box<bindings::bt_callbacks_t>>,
-}
-
+/// Macro to call functions via function pointers. Expects the self object to
+/// have a raw interface wrapper at `self.internal`. The actual function call is
+/// marked unsafe since it will need to dereference a C object. This can cause
+/// segfaults if not validated beforehand.
+///
+/// Example:
+/// ccall!(self, foobar, arg1, arg2)
+/// Expands to: unsafe {((*self.internal.raw).foobar.unwrap())(arg1, arg2)}
#[macro_export]
macro_rules! ccall {
($self:ident,$fn_name:ident) => {
@@ -779,7 +780,51 @@ macro_rules! ccall {
unsafe {
((*$self.internal.raw).$fn_name.unwrap())($($args),*)
}
- }
+ };
+}
+
+/// Macro to call const functions via cxx. Expects the self object to have the
+/// cxx object to be called at `self.internal_cxx`.
+///
+/// Example:
+/// cxxcall!(self, foobar, arg1, arg2)
+/// Expands to: self.internal_cxx.foobar(arg1, arg2)
+#[macro_export]
+macro_rules! cxxcall {
+ ($self:expr,$fn_name:ident) => {
+ $self.internal_cxx.$fn_name()
+ };
+ ($self:expr,$fn_name:ident, $($args:expr),*) => {
+ $self.internal_cxx.$fn_name($($args),*)
+ };
+}
+
+/// Macro to call mutable functions via cxx. Mutable functions are always
+/// required to be defined with `self: Pin<&mut Self>`. The self object must
+/// have the cxx object at `self.internal_cxx`.
+///
+/// Example:
+/// mutcxxcall!(self, foobar, arg1, arg2)
+/// Expands to: self.internal_cxx.pin_mut().foobar(arg1, arg2)
+#[macro_export]
+macro_rules! mutcxxcall {
+ ($self:expr,$fn_name:ident) => {
+ $self.internal_cxx.pin_mut().$fn_name()
+ };
+ ($self:expr,$fn_name:ident, $($args:expr),*) => {
+ $self.internal_cxx.pin_mut().$fn_name($($args),*)
+ };
+}
+
+/// Rust wrapper around `bt_interface_t`.
+pub struct BluetoothInterface {
+ internal: RawInterfaceWrapper,
+
+ /// Set to true after `initialize` is called.
+ pub is_init: bool,
+
+ // Need to take ownership of callbacks so it doesn't get freed after init
+ callbacks: Option<Box<bindings::bt_callbacks_t>>,
}
impl BluetoothInterface {
@@ -787,6 +832,12 @@ impl BluetoothInterface {
self.is_init
}
+ /// Initialize the Bluetooth interface by setting up the underlying interface.
+ ///
+ /// # Arguments
+ ///
+ /// * `callbacks` - Dispatcher struct that accepts [`BaseCallbacks`]
+ /// * `init_flags` - List of flags sent to libbluetooth for init.
pub fn initialize(
&mut self,
callbacks: BaseCallbacksDispatcher,
@@ -953,6 +1004,10 @@ impl BluetoothInterface {
ccall!(self, ssp_reply, ffi_addr, cvariant, accept, passkey)
}
+ pub fn clear_event_filter(&self) -> i32 {
+ ccall!(self, clear_event_filter)
+ }
+
pub(crate) fn get_profile_interface(
&self,
profile: SupportedProfiles,
diff --git a/system/gd/rust/topshim/src/lib.rs b/system/gd/rust/topshim/src/lib.rs
index c240ba8118..74b622f90d 100644
--- a/system/gd/rust/topshim/src/lib.rs
+++ b/system/gd/rust/topshim/src/lib.rs
@@ -1,4 +1,16 @@
-//! The main entry point for Rust to C++.
+//! Topshim is the main entry point from Rust code to C++.
+//!
+//! The Bluetooth stack is split into two parts: libbluetooth and the framework
+//! above it. Libbluetooth is a combination of C/C++ and Rust that provides the
+//! core Bluetooth functionality. It exposes top level apis in `bt_interface_t`
+//! which can be used to drive the underlying implementation. Topshim provides
+//! Rust apis to access this C/C++ interface and other top level interfaces in
+//! order to use libbluetooth.
+//!
+//! The expected users of Topshim:
+//! * Floss (ChromeOS + Linux Bluetooth stack; uses D-Bus)
+//! * Topshim facade (used for testing)
+
#[macro_use]
extern crate lazy_static;
#[macro_use]
@@ -6,8 +18,14 @@ extern crate num_derive;
#[macro_use]
extern crate bitflags;
+/// Bindgen bindings for accessing libbluetooth.
pub mod bindings;
+
pub mod btif;
+
+/// Helper module for the topshim facade.
pub mod controller;
+
pub mod profiles;
+
pub mod topstack;
diff --git a/system/gd/rust/topshim/src/profiles/gatt.rs b/system/gd/rust/topshim/src/profiles/gatt.rs
index ebb6bed748..2a71b282a5 100644
--- a/system/gd/rust/topshim/src/profiles/gatt.rs
+++ b/system/gd/rust/topshim/src/profiles/gatt.rs
@@ -8,7 +8,7 @@ use crate::profiles::gatt::bindings::{
BleAdvertiserInterface, BleScannerInterface,
};
use crate::topstack::get_dispatchers;
-use crate::{cast_to_ffi_address, ccall, deref_ffi_address};
+use crate::{cast_to_ffi_address, ccall, deref_ffi_address, mutcxxcall};
use num_traits::cast::FromPrimitive;
@@ -29,6 +29,11 @@ pub mod ffi {
address: [u8; 6],
}
+ #[derive(Debug, Copy, Clone)]
+ pub struct RustUuid {
+ uu: [u8; 16],
+ }
+
#[derive(Debug, Clone)]
pub struct RustAdvertisingTrackInfo {
scanner_id: u8,
@@ -46,6 +51,37 @@ pub mod ffi {
scan_response: Vec<u8>,
}
+ // Original definition exists in C++.
+ #[derive(Debug, Clone)]
+ pub struct RustGattFilterParam {
+ feat_seln: u16,
+ list_logic_type: u16,
+ filt_logic_type: u8,
+ rssi_high_thres: u8,
+ rssi_low_thres: u8,
+ delay_mode: u8,
+ found_timeout: u16,
+ lost_timeout: u16,
+ found_timeout_count: u8,
+ num_of_tracking_entries: u16,
+ }
+
+ // Defined in C++ and needs a translation in shim.
+ #[derive(Debug, Clone)]
+ pub struct RustApcfCommand {
+ type_: u8,
+ address: RustRawAddress,
+ addr_type: u8,
+ uuid: RustUuid,
+ uuid_mask: RustUuid,
+ name: Vec<u8>,
+ company: u16,
+ company_mask: u16,
+ data: Vec<u8>,
+ data_mask: Vec<u8>,
+ irk: [u8; 16],
+ }
+
unsafe extern "C++" {
include!("gatt/gatt_shim.h");
@@ -75,7 +111,76 @@ pub mod ffi {
unsafe fn GetBleScannerIntf(gatt: *const u8) -> UniquePtr<BleScannerIntf>;
- // TODO - Implement the rest of the BleScannerIntf
+ fn RegisterScanner(self: Pin<&mut BleScannerIntf>, uuid: RustUuid);
+ fn Unregister(self: Pin<&mut BleScannerIntf>, scanner_id: u8);
+ fn Scan(self: Pin<&mut BleScannerIntf>, start: bool);
+ fn ScanFilterParamSetup(
+ self: Pin<&mut BleScannerIntf>,
+ scanner_id: u8,
+ action: u8,
+ filter_index: u8,
+ filt_param: RustGattFilterParam,
+ );
+ fn ScanFilterAdd(
+ self: Pin<&mut BleScannerIntf>,
+ filter_index: u8,
+ filters: Vec<RustApcfCommand>,
+ );
+ fn ScanFilterClear(self: Pin<&mut BleScannerIntf>, filter_index: u8);
+ fn ScanFilterEnable(self: Pin<&mut BleScannerIntf>, enable: bool);
+ fn SetScanParameters(
+ self: Pin<&mut BleScannerIntf>,
+ scanner_id: u8,
+ scan_interval: u16,
+ scan_window: u16,
+ );
+
+ fn BatchscanConfigStorage(
+ self: Pin<&mut BleScannerIntf>,
+ scanner_id: u8,
+ batch_scan_full_max: i32,
+ batch_scan_trunc_max: i32,
+ batch_scan_notify_threshold: i32,
+ );
+ fn BatchscanEnable(
+ self: Pin<&mut BleScannerIntf>,
+ scan_mode: i32,
+ scan_interval: u16,
+ scan_window: u16,
+ addr_type: i32,
+ discard_rule: i32,
+ );
+ fn BatchscanDisable(self: Pin<&mut BleScannerIntf>);
+ fn BatchscanReadReports(self: Pin<&mut BleScannerIntf>, scanner_id: u8, scan_mode: i32);
+
+ fn StartSync(
+ self: Pin<&mut BleScannerIntf>,
+ sid: u8,
+ address: RustRawAddress,
+ skip: u16,
+ timeout: u16,
+ );
+ fn StopSync(self: Pin<&mut BleScannerIntf>, handle: u16);
+ fn CancelCreateSync(self: Pin<&mut BleScannerIntf>, sid: u8, address: RustRawAddress);
+ fn TransferSync(
+ self: Pin<&mut BleScannerIntf>,
+ address: RustRawAddress,
+ service_data: u16,
+ sync_handle: u16,
+ );
+ fn TransferSetInfo(
+ self: Pin<&mut BleScannerIntf>,
+ address: RustRawAddress,
+ service_data: u16,
+ adv_handle: u8,
+ );
+ fn SyncTxParameters(
+ self: Pin<&mut BleScannerIntf>,
+ address: RustRawAddress,
+ mode: u8,
+ skip: u16,
+ timeout: u16,
+ );
/// Registers a C++ |ScanningCallbacks| implementation with the BleScanner.
/// The shim implementation will call all the callbacks defined via |cb_variant!|.
@@ -83,7 +188,6 @@ pub mod ffi {
}
extern "Rust" {
-
// All callbacks below are generated by cb_variant! and will be called
// by the ScanningCallbacks handler in shim.
unsafe fn gdscan_on_scanner_registered(uuid: *const i8, scannerId: u8, status: u8);
@@ -111,10 +215,61 @@ pub mod ffi {
data_len: usize,
);
unsafe fn gdscan_on_batch_scan_threshold_crossed(client_if: i32);
+
+ // Static cb_variant! callbacks using base::Callback
+ unsafe fn gdscan_register_callback(uuid: RustUuid, scanner_id: u8, btm_status: u8);
+ unsafe fn gdscan_status_callback(scanner_id: u8, btm_status: u8);
+ unsafe fn gdscan_enable_callback(action: u8, btm_status: u8);
+ unsafe fn gdscan_filter_param_setup_callback(
+ scanner_id: u8,
+ available_space: u8,
+ action: u8,
+ btm_status: u8,
+ );
+ unsafe fn gdscan_filter_config_callback(
+ filter_index: u8,
+ filter_type: u8,
+ available_space: u8,
+ action: u8,
+ btm_status: u8,
+ );
+ unsafe fn gdscan_start_sync_callback(
+ status: u8,
+ sync_handle: u16,
+ advertising_sid: u8,
+ addr_type: u8,
+ address: *const RustRawAddress,
+ phy: u8,
+ interval: u16,
+ );
+ unsafe fn gdscan_sync_report_callback(
+ sync_handle: u16,
+ tx_power: i8,
+ rssi: i8,
+ status: u8,
+ data: *const u8,
+ len: usize,
+ );
+ unsafe fn gdscan_sync_lost_callback(sync_handle: u16);
+ unsafe fn gdscan_sync_transfer_callback(status: u8, address: *const RustRawAddress);
}
}
pub type AdvertisingTrackInfo = ffi::RustAdvertisingTrackInfo;
+pub type GattFilterParam = ffi::RustGattFilterParam;
+pub type ApcfCommand = ffi::RustApcfCommand;
+
+impl From<ffi::RustUuid> for Uuid {
+ fn from(item: ffi::RustUuid) -> Self {
+ Uuid { uu: item.uu }
+ }
+}
+
+impl From<Uuid> for ffi::RustUuid {
+ fn from(item: Uuid) -> Self {
+ ffi::RustUuid { uu: item.uu }
+ }
+}
#[derive(Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
#[repr(u32)]
@@ -532,6 +687,72 @@ cb_variant!(
cb_variant!(GDScannerCb, gdscan_on_batch_scan_threshold_crossed -> GattScannerCallbacks::OnBatchScanThresholdCrossed, i32);
+/// In-band callbacks from the various |BleScannerInterface| methods. Rather than
+/// store closures for each registered callback, we instead bind and return an
+/// identifier for the callback instead (such as scanner id or Uuid).
+#[derive(Debug)]
+pub enum GattScannerInbandCallbacks {
+ /// Params: App Uuid, Scanner Id, BTM Status
+ RegisterCallback(Uuid, u8, u8),
+
+ /// Params: Scanner Id, BTM Status
+ StatusCallback(u8, u8),
+
+ /// Params: Action (enable/disable), BTM Status
+ EnableCallback(u8, u8),
+
+ /// Params: Scanner Id, Available Space, Action Type, BTM Status
+ FilterParamSetupCallback(u8, u8, u8, u8),
+
+ /// Params: Filter Index, Filter Type, Available Space, Action, BTM Status
+ FilterConfigCallback(u8, u8, u8, u8, u8),
+
+ /// Params: Status, Sync Handle, Advertising Sid, Address Type, Address, Phy, Interval
+ StartSyncCallback(u8, u16, u8, u8, RawAddress, u8, u16),
+
+ /// Params: Sync Handle, Tx Power, RSSI, Status, Data
+ SyncReportCallback(u16, i8, i8, u8, Vec<u8>),
+
+ /// Params: Sync Handle
+ SyncLostCallback(u16),
+
+ /// Params: Status, Address
+ SyncTransferCallback(u8, RawAddress),
+}
+
+pub struct GattScannerInbandCallbacksDispatcher {
+ pub dispatch: Box<dyn Fn(GattScannerInbandCallbacks) + Send>,
+}
+
+type GDScannerInbandCb = Arc<Mutex<GattScannerInbandCallbacksDispatcher>>;
+
+cb_variant!(GDScannerInbandCb, gdscan_register_callback -> GattScannerInbandCallbacks::RegisterCallback,
+ ffi::RustUuid -> Uuid, u8, u8);
+
+cb_variant!(GDScannerInbandCb, gdscan_status_callback -> GattScannerInbandCallbacks::StatusCallback, u8, u8);
+cb_variant!(GDScannerInbandCb, gdscan_enable_callback -> GattScannerInbandCallbacks::EnableCallback, u8, u8);
+cb_variant!(GDScannerInbandCb,
+ gdscan_filter_param_setup_callback -> GattScannerInbandCallbacks::FilterParamSetupCallback,
+ u8, u8, u8, u8);
+cb_variant!(GDScannerInbandCb,
+ gdscan_filter_config_callback -> GattScannerInbandCallbacks::FilterConfigCallback,
+ u8, u8, u8, u8, u8);
+cb_variant!(GDScannerInbandCb,
+gdscan_start_sync_callback -> GattScannerInbandCallbacks::StartSyncCallback,
+u8, u16, u8, u8, *const ffi::RustRawAddress, u8, u16, {
+ let _4 = unsafe { deref_ffi_address!(_4) };
+});
+cb_variant!(GDScannerInbandCb,
+gdscan_sync_report_callback -> GattScannerInbandCallbacks::SyncReportCallback,
+u16, i8, i8, u8, *const u8, usize -> _, {
+ let _4 = ptr_to_vec(_4, _5 as usize);
+});
+cb_variant!(GDScannerInbandCb, gdscan_sync_lost_callback -> GattScannerInbandCallbacks::SyncLostCallback, u16);
+cb_variant!(GDScannerInbandCb, gdscan_sync_transfer_callback -> GattScannerInbandCallbacks::SyncTransferCallback,
+u8, *const ffi::RustRawAddress, {
+ let _1 = unsafe { deref_ffi_address!(_1) };
+});
+
struct RawGattWrapper {
raw: *const btgatt_interface_t,
}
@@ -761,11 +982,12 @@ impl GattClient {
}
pub fn read_phy(&mut self, client_if: i32, addr: &RawAddress) -> BtStatus {
- BtStatus::from_i32(
- self.internal_cxx
- .pin_mut()
- .read_phy(client_if, ffi::RustRawAddress { address: addr.val }),
- )
+ BtStatus::from_i32(mutcxxcall!(
+ self,
+ read_phy,
+ client_if,
+ ffi::RustRawAddress { address: addr.val }
+ ))
.unwrap()
}
@@ -863,7 +1085,6 @@ impl GattServer {
// TODO(b/193916778): Figure out how to shim read_phy which accepts base::Callback
}
-// TODO(b/193916778): Underlying FFI is C++, implement using cxx.
pub struct BleScanner {
internal: RawBleScannerWrapper,
internal_cxx: cxx::UniquePtr<ffi::BleScannerIntf>,
@@ -881,6 +1102,125 @@ impl BleScanner {
internal_cxx,
}
}
+
+ fn register_scanner(&mut self, app_uuid: Uuid) {
+ mutcxxcall!(self, RegisterScanner, app_uuid.into());
+ }
+
+ fn unregister(&mut self, scanner_id: u8) {
+ mutcxxcall!(self, Unregister, scanner_id);
+ }
+
+ fn start_scan(&mut self) {
+ mutcxxcall!(self, Scan, true);
+ }
+
+ fn stop_scan(&mut self) {
+ mutcxxcall!(self, Scan, false);
+ }
+
+ fn scan_filter_setup(
+ &mut self,
+ scanner_id: u8,
+ action: u8,
+ filter_index: u8,
+ param: GattFilterParam,
+ ) {
+ mutcxxcall!(self, ScanFilterParamSetup, scanner_id, action, filter_index, param);
+ }
+
+ fn scan_filter_add(&mut self, filter_index: u8, filters: Vec<ApcfCommand>) {
+ mutcxxcall!(self, ScanFilterAdd, filter_index, filters);
+ }
+
+ fn scan_filter_clear(&mut self, filter_index: u8) {
+ mutcxxcall!(self, ScanFilterClear, filter_index);
+ }
+
+ fn scan_filter_enable(&mut self) {
+ mutcxxcall!(self, ScanFilterEnable, true);
+ }
+
+ fn scan_filter_disable(&mut self) {
+ mutcxxcall!(self, ScanFilterEnable, false);
+ }
+
+ fn set_scan_parameters(&mut self, scanner_id: u8, scan_interval: u16, scan_window: u16) {
+ mutcxxcall!(self, SetScanParameters, scanner_id, scan_interval, scan_window);
+ }
+
+ fn batchscan_config_storage(
+ &mut self,
+ scanner_id: u8,
+ full_max: i32,
+ trunc_max: i32,
+ notify_threshold: i32,
+ ) {
+ mutcxxcall!(
+ self,
+ BatchscanConfigStorage,
+ scanner_id,
+ full_max,
+ trunc_max,
+ notify_threshold
+ );
+ }
+
+ fn batchscan_enable(
+ &mut self,
+ scan_mode: i32,
+ scan_interval: u16,
+ scan_window: u16,
+ addr_type: i32,
+ discard_rule: i32,
+ ) {
+ mutcxxcall!(
+ self,
+ BatchscanEnable,
+ scan_mode,
+ scan_interval,
+ scan_window,
+ addr_type,
+ discard_rule
+ );
+ }
+
+ fn batchscan_disable(&mut self) {
+ mutcxxcall!(self, BatchscanDisable);
+ }
+
+ fn batchscan_read_reports(&mut self, scanner_id: u8, scan_mode: i32) {
+ mutcxxcall!(self, BatchscanReadReports, scanner_id, scan_mode);
+ }
+
+ fn start_sync(&mut self, sid: u8, address: RawAddress, skip: u16, timeout: u16) {
+ let addr = unsafe { *((&address as *const RawAddress) as *const ffi::RustRawAddress) };
+ mutcxxcall!(self, StartSync, sid, addr, skip, timeout);
+ }
+
+ fn stop_sync(&mut self, handle: u16) {
+ mutcxxcall!(self, StopSync, handle);
+ }
+
+ fn cancel_create_sync(&mut self, sid: u8, address: RawAddress) {
+ let addr = unsafe { *((&address as *const RawAddress) as *const ffi::RustRawAddress) };
+ mutcxxcall!(self, CancelCreateSync, sid, addr);
+ }
+
+ fn transfer_sync(&mut self, address: RawAddress, service_data: u16, sync_handle: u16) {
+ let addr = unsafe { *((&address as *const RawAddress) as *const ffi::RustRawAddress) };
+ mutcxxcall!(self, TransferSync, addr, service_data, sync_handle);
+ }
+
+ fn transfer_set_info(&mut self, address: RawAddress, service_data: u16, adv_handle: u8) {
+ let addr = unsafe { *((&address as *const RawAddress) as *const ffi::RustRawAddress) };
+ mutcxxcall!(self, TransferSetInfo, addr, service_data, adv_handle);
+ }
+
+ fn sync_tx_parameters(&mut self, address: RawAddress, mode: u8, skip: u16, timeout: u16) {
+ let addr = unsafe { *((&address as *const RawAddress) as *const ffi::RustRawAddress) };
+ mutcxxcall!(self, SyncTxParameters, addr, mode, skip, timeout);
+ }
}
// TODO(b/193916778): Underlying FFI is C++, implement using cxx.
@@ -1053,7 +1393,7 @@ impl Gatt {
self.gatt_scanner_callbacks = Some(gatt_scanner_callbacks);
// Register callbacks for gatt scanner
- self.scanner.internal_cxx.pin_mut().RegisterCallbacks();
+ mutcxxcall!(self.scanner, RegisterCallbacks);
return self.is_init;
}
diff --git a/system/gd/rust/topshim/src/profiles/mod.rs b/system/gd/rust/topshim/src/profiles/mod.rs
index a12e7c5048..283ae9b294 100644
--- a/system/gd/rust/topshim/src/profiles/mod.rs
+++ b/system/gd/rust/topshim/src/profiles/mod.rs
@@ -1,3 +1,5 @@
+//! Various libraries to access the profile interfaces.
+
pub mod a2dp;
pub mod avrcp;
pub mod gatt;
diff --git a/system/gd/rust/topshim/src/topstack.rs b/system/gd/rust/topshim/src/topstack.rs
index 7553863ec3..18edf5d2e3 100644
--- a/system/gd/rust/topshim/src/topstack.rs
+++ b/system/gd/rust/topshim/src/topstack.rs
@@ -29,13 +29,53 @@ lazy_static! {
Arc::new(Mutex::new(DispatchContainer { instances: HashMap::new() }));
}
-type InstanceBox = Box<dyn Any + Send + Sync>;
+/// A Box-ed struct that implements a `dispatch` fn.
+///
+/// Example:
+/// ```
+/// use std::sync::Arc;
+/// use std::sync::Mutex;
+///
+/// #[derive(Debug)]
+/// enum Foo {
+/// First(i16),
+/// Second(i32),
+/// }
+///
+/// struct FooDispatcher {
+/// dispatch: Box<dyn Fn(Foo) + Send>,
+/// }
+///
+/// fn main() {
+/// let foo_dispatcher = FooDispatcher {
+/// dispatch: Box::new(move |value| {
+/// println!("Dispatch {:?}", value);
+/// })
+/// };
+/// let value = Arc::new(Mutex::new(foo_dispatcher));
+/// let instance_box = Box::new(value);
+/// }
+/// ```
+pub type InstanceBox = Box<dyn Any + Send + Sync>;
+/// Manage enum dispatches for emulating callbacks.
+///
+/// Libbluetooth is highly callback based but our Rust code prefers using
+/// channels. To reconcile these two systems, we pass static callbacks to
+/// libbluetooth that convert callback args into an enum variant and call the
+/// dispatcher for that enum. The dispatcher will then queue that enum into the
+/// channel (using a captured channel tx in the closure).
pub struct DispatchContainer {
instances: HashMap<TypeId, InstanceBox>,
}
impl DispatchContainer {
+ /// Find registered dispatcher for enum specialization.
+ ///
+ /// # Return
+ ///
+ /// Returns an Option with a dispatcher object (the contents of
+ /// [`InstanceBox`]).
pub fn get<T: 'static + Clone + Send + Sync>(&self) -> Option<T> {
let typeid = TypeId::of::<T>();
@@ -46,11 +86,22 @@ impl DispatchContainer {
None
}
+ /// Set dispatcher for an enum specialization.
+ ///
+ /// # Arguments
+ ///
+ /// * `obj` - The contents of [`InstanceBox`], usually `Arc<Mutex<U>>`. See
+ /// the [`InstanceBox`] documentation for examples.
+ ///
+ /// # Returns
+ ///
+ /// True if this is replacing an existing enum dispatcher.
pub fn set<T: 'static + Clone + Send + Sync>(&mut self, obj: T) -> bool {
self.instances.insert(TypeId::of::<T>(), Box::new(obj)).is_some()
}
}
+/// Take a clone of the static dispatcher container.
pub fn get_dispatchers() -> Arc<Mutex<DispatchContainer>> {
CB_DISPATCHER.clone()
}
diff --git a/system/gd/security/facade_configuration_api.h b/system/gd/security/facade_configuration_api.h
index d6bab79579..9feb8a4600 100644
--- a/system/gd/security/facade_configuration_api.h
+++ b/system/gd/security/facade_configuration_api.h
@@ -35,6 +35,9 @@ namespace security {
*/
class FacadeConfigurationApi {
public:
+ FacadeConfigurationApi(const FacadeConfigurationApi&) = delete;
+ FacadeConfigurationApi& operator=(const FacadeConfigurationApi&) = delete;
+
friend class internal::SecurityManagerImpl;
friend class SecurityModule;
@@ -63,7 +66,6 @@ class FacadeConfigurationApi {
private:
os::Handler* security_handler_ = nullptr;
internal::SecurityManagerImpl* security_manager_impl_;
- DISALLOW_COPY_AND_ASSIGN(FacadeConfigurationApi);
};
} // namespace security
diff --git a/system/gd/security/security_manager.h b/system/gd/security/security_manager.h
index 627cc2ac89..1842761187 100644
--- a/system/gd/security/security_manager.h
+++ b/system/gd/security/security_manager.h
@@ -36,6 +36,9 @@ namespace security {
*/
class SecurityManager : public UICallbacks {
public:
+ SecurityManager(const SecurityManager&) = delete;
+ SecurityManager& operator=(const SecurityManager&) = delete;
+
friend class SecurityModule;
/**
@@ -133,7 +136,6 @@ class SecurityManager : public UICallbacks {
private:
os::Handler* security_handler_ = nullptr;
internal::SecurityManagerImpl* security_manager_impl_;
- DISALLOW_COPY_AND_ASSIGN(SecurityManager);
};
} // namespace security
diff --git a/system/gd/security/security_module.h b/system/gd/security/security_module.h
index 889073388a..68ba2dacd1 100644
--- a/system/gd/security/security_module.h
+++ b/system/gd/security/security_module.h
@@ -27,6 +27,9 @@ namespace security {
class SecurityModule : public bluetooth::Module {
public:
SecurityModule() = default;
+ SecurityModule(const SecurityModule&) = delete;
+ SecurityModule& operator=(const SecurityModule&) = delete;
+
~SecurityModule() = default;
/**
@@ -55,7 +58,6 @@ class SecurityModule : public bluetooth::Module {
private:
struct impl;
std::unique_ptr<impl> pimpl_;
- DISALLOW_COPY_AND_ASSIGN(SecurityModule);
};
} // namespace security
diff --git a/system/gd/security/test/mocks.h b/system/gd/security/test/mocks.h
index 3ddc909f4c..dc8d3254db 100644
--- a/system/gd/security/test/mocks.h
+++ b/system/gd/security/test/mocks.h
@@ -30,6 +30,9 @@ namespace security {
class UIMock : public UI {
public:
UIMock() = default;
+ UIMock(const UIMock&) = delete;
+ UIMock& operator=(const UIMock&) = delete;
+
~UIMock() = default;
// Convert these to accept ConfirmationData
@@ -40,9 +43,6 @@ class UIMock : public UI {
MOCK_METHOD1(DisplayEnterPasskeyDialog, void(ConfirmationData));
MOCK_METHOD1(DisplayPasskey, void(ConfirmationData));
MOCK_METHOD1(DisplayEnterPinDialog, void(ConfirmationData));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(UIMock);
};
class LeSecurityInterfaceMock : public hci::LeSecurityInterface {
diff --git a/system/gd/shim/dumpsys.h b/system/gd/shim/dumpsys.h
index 35c1936d77..04be062793 100644
--- a/system/gd/shim/dumpsys.h
+++ b/system/gd/shim/dumpsys.h
@@ -36,6 +36,10 @@ class Dumpsys : public bluetooth::Module {
os::Handler* GetGdShimHandler();
Dumpsys(const std::string& pre_bundled_schema);
+
+ Dumpsys(const Dumpsys&) = delete;
+ Dumpsys& operator=(const Dumpsys&) = delete;
+
~Dumpsys() = default;
static const ModuleFactory Factory;
@@ -51,7 +55,6 @@ class Dumpsys : public bluetooth::Module {
struct impl;
std::unique_ptr<impl> pimpl_;
const dumpsys::ReflectionSchema reflection_schema_;
- DISALLOW_COPY_AND_ASSIGN(Dumpsys);
};
} // namespace shim
diff --git a/system/gd/storage/config_cache.h b/system/gd/storage/config_cache.h
index f0e1fe456b..44229e473d 100644
--- a/system/gd/storage/config_cache.h
+++ b/system/gd/storage/config_cache.h
@@ -52,10 +52,13 @@ class Mutation;
class ConfigCache {
public:
ConfigCache(size_t temp_device_capacity, std::unordered_set<std::string_view> persistent_property_names);
+
+ ConfigCache(const ConfigCache&) = delete;
+ ConfigCache& operator=(const ConfigCache&) = delete;
+
virtual ~ConfigCache() = default;
// no copy
- DISALLOW_COPY_AND_ASSIGN(ConfigCache);
// can move
ConfigCache(ConfigCache&& other) noexcept;
diff --git a/system/gd/storage/storage_module.h b/system/gd/storage/storage_module.h
index 8853a4e76f..ba41b1a5eb 100644
--- a/system/gd/storage/storage_module.h
+++ b/system/gd/storage/storage_module.h
@@ -47,6 +47,9 @@ class StorageModule : public bluetooth::Module {
static const std::string kAdapterSection;
+ StorageModule(const StorageModule&) = delete;
+ StorageModule& operator=(const StorageModule&) = delete;
+
~StorageModule();
static const ModuleFactory Factory;
@@ -146,8 +149,6 @@ class StorageModule : public bluetooth::Module {
bool is_restricted_mode_;
bool is_single_user_mode_;
static bool is_config_checksum_pass(int check_bit);
-
- DISALLOW_COPY_AND_ASSIGN(StorageModule);
};
} // namespace storage
diff --git a/system/include/hardware/bluetooth.h b/system/include/hardware/bluetooth.h
index 65c9db2f33..16130873a9 100644
--- a/system/include/hardware/bluetooth.h
+++ b/system/include/hardware/bluetooth.h
@@ -282,11 +282,11 @@ typedef enum {
*/
BT_PROPERTY_ADAPTER_BONDED_DEVICES,
/**
- * Description - Bluetooth Adapter Discovery timeout (in seconds)
+ * Description - Bluetooth Adapter Discoverable timeout (in seconds)
* Access mode - GET and SET
* Data type - uint32_t
*/
- BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT,
+ BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT,
/* Properties unique to remote device */
/**
@@ -472,8 +472,7 @@ typedef void (*link_quality_report_callback)(
int negative_acknowledgement_count);
/** Switch the buffer size callback */
-typedef void (*switch_buffer_size_callback)(RawAddress* remote_addr,
- bool is_low_latency_buffer_size);
+typedef void (*switch_buffer_size_callback)(bool is_low_latency_buffer_size);
typedef enum { ASSOCIATE_JVM, DISASSOCIATE_JVM } bt_cb_thread_evt;
@@ -772,6 +771,11 @@ typedef struct {
* @return true if audio low latency is successfully allowed or disallowed
*/
bool (*allow_low_latency_audio)(bool allowed, const RawAddress& address);
+
+ /**
+ * Set the event filter for the controller
+ */
+ int (*clear_event_filter)();
} bt_interface_t;
#define BLUETOOTH_INTERFACE_STRING "bluetoothInterface"
diff --git a/system/include/hardware/bt_has.h b/system/include/hardware/bt_has.h
index 4fdd316852..739edc041f 100644
--- a/system/include/hardware/bt_has.h
+++ b/system/include/hardware/bt_has.h
@@ -36,9 +36,10 @@ enum class ConnectionState : uint8_t {
/** Results codes for the failed preset operations */
enum class ErrorCode : uint8_t {
NO_ERROR = 0,
- SET_NAME_NOT_ALLOWED,
- OPERATION_NOT_SUPPORTED,
- OPERATION_NOT_POSSIBLE,
+ SET_NAME_NOT_ALLOWED, // Preset cannot be written (read only preset)
+ OPERATION_NOT_SUPPORTED, // If theres no optional characteristic,
+ // or request opcode is invalid or not supported
+ OPERATION_NOT_POSSIBLE, // Operation cannot be performed at this time
INVALID_PRESET_NAME_LENGTH,
INVALID_PRESET_INDEX,
GROUP_OPERATION_NOT_SUPPORTED,
diff --git a/system/include/hardware/bt_vc.h b/system/include/hardware/bt_vc.h
index fb0b725fac..e7f498b6cb 100644
--- a/system/include/hardware/bt_vc.h
+++ b/system/include/hardware/bt_vc.h
@@ -42,11 +42,11 @@ class VolumeControlCallbacks {
/* Callback for the volume change changed on the device */
virtual void OnVolumeStateChanged(const RawAddress& address, uint8_t volume,
- bool mute) = 0;
+ bool mute, bool isAutonomous) = 0;
/* Callback for the volume change changed on the group*/
virtual void OnGroupVolumeStateChanged(int group_id, uint8_t volume,
- bool mute) = 0;
+ bool mute, bool isAutonomous) = 0;
};
class VolumeControlInterface {
diff --git a/system/main/Android.bp b/system/main/Android.bp
index bd331e62f4..812340d79b 100644
--- a/system/main/Android.bp
+++ b/system/main/Android.bp
@@ -99,7 +99,6 @@ cc_library_shared {
"libbt-sbc-encoder",
"libFraunhoferAAC",
"libg722codec",
- "liblc3codec",
"liblc3",
"libudrv-uipc",
"libprotobuf-cpp-lite",
@@ -125,7 +124,6 @@ cc_library_shared {
"android.hardware.bluetooth.a2dp@1.0",
"android.hardware.bluetooth.audio@2.0",
"android.hardware.bluetooth.audio@2.1",
- "android.hardware.bluetooth.audio@2.2",
"android.hardware.bluetooth.audio-V1-ndk",
"android.hardware.bluetooth@1.0",
"android.hardware.bluetooth@1.1",
@@ -156,6 +154,10 @@ cc_library_shared {
required: [
"bt_did.conf",
"bt_stack.conf",
+ "audio_set_scenarios_bfbs",
+ "audio_set_scenarios_json",
+ "audio_set_configurations_bfbs",
+ "audio_set_configurations_json",
],
cflags: [
"-DBUILDCFG",
diff --git a/system/main/shim/acl.h b/system/main/shim/acl.h
index d156f85d46..f90e641455 100644
--- a/system/main/shim/acl.h
+++ b/system/main/shim/acl.h
@@ -43,6 +43,10 @@ class Acl : public hci::acl_manager::ConnectionCallbacks,
public:
Acl(os::Handler* handler, const acl_interface_t& acl_interface,
uint8_t max_acceptlist_size, uint8_t max_address_resolution_size);
+
+ Acl(const Acl&) = delete;
+ Acl& operator=(const Acl&) = delete;
+
~Acl();
// hci::acl_manager::ConnectionCallbacks
@@ -120,7 +124,6 @@ class Acl : public hci::acl_manager::ConnectionCallbacks,
struct impl;
std::unique_ptr<impl> pimpl_;
- DISALLOW_COPY_AND_ASSIGN(Acl);
};
} // namespace legacy
diff --git a/system/main/shim/btm.cc b/system/main/shim/btm.cc
index b79292c72c..29827208d3 100644
--- a/system/main/shim/btm.cc
+++ b/system/main/shim/btm.cc
@@ -55,8 +55,8 @@ static constexpr bool kPassiveScanning = false;
using BtmRemoteDeviceName = tBTM_REMOTE_DEV_NAME;
-extern void btm_process_cancel_complete(uint8_t status, uint8_t mode);
-extern void btm_process_inq_complete(uint8_t status, uint8_t result_type);
+extern void btm_process_cancel_complete(tHCI_STATUS status, uint8_t mode);
+extern void btm_process_inq_complete(tHCI_STATUS status, uint8_t result_type);
extern void btm_ble_process_adv_addr(RawAddress& raw_address,
tBLE_ADDR_TYPE* address_type);
extern void btm_ble_process_adv_pkt_cont(
diff --git a/system/main/shim/btm_api.cc b/system/main/shim/btm_api.cc
index a4ad2f913f..d5f3023c4e 100644
--- a/system/main/shim/btm_api.cc
+++ b/system/main/shim/btm_api.cc
@@ -71,7 +71,7 @@ extern void btm_clear_all_pending_le_entry(void);
extern void btm_clr_inq_result_flt(void);
extern void btm_set_eir_uuid(const uint8_t* p_eir, tBTM_INQ_RESULTS* p_results);
extern void btm_sort_inq_result(void);
-extern void btm_process_inq_complete(uint8_t status, uint8_t result_type);
+extern void btm_process_inq_complete(tHCI_STATUS status, uint8_t result_type);
static bool is_classic_device(tBT_DEVICE_TYPE device_type) {
return device_type == BT_DEVICE_TYPE_BREDR;
@@ -1341,3 +1341,8 @@ tBTM_STATUS bluetooth::shim::BTM_SetDeviceClass(DEV_CLASS dev_class) {
LOG_WARN("Unimplemented");
return BTM_SUCCESS;
}
+
+tBTM_STATUS bluetooth::shim::BTM_ClearEventFilter() {
+ controller_get_interface()->clear_event_filter();
+ return BTM_SUCCESS;
+}
diff --git a/system/main/shim/btm_api.h b/system/main/shim/btm_api.h
index 5a4f42f081..3f864b4c0f 100644
--- a/system/main/shim/btm_api.h
+++ b/system/main/shim/btm_api.h
@@ -1840,6 +1840,17 @@ bool BTM_BleLocalPrivacyEnabled(void);
******************************************************************************/
tBTM_STATUS BTM_BleGetEnergyInfo(tBTM_BLE_ENERGY_INFO_CBACK* p_ener_cback);
+/*******************************************************************************
+ *
+ * Function BTM_ClearEventFilter
+ *
+ * Description Clears the event filter in the controller
+ *
+ * Returns Return btm status
+ *
+ ******************************************************************************/
+tBTM_STATUS BTM_ClearEventFilter(void);
+
/**
* Send remote name request to GD shim Name module
*/
diff --git a/system/main/shim/controller.cc b/system/main/shim/controller.cc
index 0b3edb34df..1ac4d79053 100644
--- a/system/main/shim/controller.cc
+++ b/system/main/shim/controller.cc
@@ -313,6 +313,12 @@ static uint8_t get_le_resolving_list_size(void) {
static uint8_t get_le_all_initiating_phys() { return data_.phy; }
+static uint8_t controller_clear_event_filter() {
+ LOG_VERBOSE("Called!");
+ bluetooth::shim::GetController()->SetEventFilterClearAll();
+ return BTM_SUCCESS;
+}
+
static const controller_t interface = {
.get_is_ready = get_is_ready,
@@ -410,7 +416,8 @@ static const controller_t interface = {
.get_ble_resolving_list_max_size = get_le_resolving_list_size,
.set_ble_resolving_list_max_size = set_ble_resolving_list_max_size,
.get_local_supported_codecs = get_local_supported_codecs,
- .get_le_all_initiating_phys = get_le_all_initiating_phys};
+ .get_le_all_initiating_phys = get_le_all_initiating_phys,
+ .clear_event_filter = controller_clear_event_filter};
const controller_t* bluetooth::shim::controller_get_interface() {
static bool loaded = false;
diff --git a/system/main/shim/le_scanning_manager.cc b/system/main/shim/le_scanning_manager.cc
index bcc8b1a647..7bd81e30bc 100644
--- a/system/main/shim/le_scanning_manager.cc
+++ b/system/main/shim/le_scanning_manager.cc
@@ -132,7 +132,9 @@ void BleScannerInterfaceImpl::Scan(bool start) {
BTM_LogHistory(
kBtmLogTag, RawAddress::kEmpty,
base::StringPrintf("Le scan %s", (start) ? "started" : "stopped"));
- address_cache_.init();
+ do_in_jni_thread(FROM_HERE,
+ base::Bind(&BleScannerInterfaceImpl::AddressCache::init,
+ base::Unretained(&address_cache_)));
}
/** Setup scan filter params */
@@ -496,6 +498,11 @@ bool BleScannerInterfaceImpl::parse_filter_command(
void BleScannerInterfaceImpl::handle_remote_properties(
RawAddress bd_addr, tBLE_ADDR_TYPE addr_type,
std::vector<uint8_t> advertising_data) {
+ if (!bluetooth::shim::is_gd_stack_started_up()) {
+ LOG_WARN("Gd stack is stopped, return");
+ return;
+ }
+
// skip anonymous advertisment
if (addr_type == BLE_ADDR_ANONYMOUS) {
return;
@@ -543,11 +550,6 @@ void BleScannerInterfaceImpl::handle_remote_properties(
}
}
}
- if (!bluetooth::shim::is_gd_stack_started_up()) {
- LOG_WARN("Gd stack is stopped, return");
- return;
- }
-
auto* storage_module = bluetooth::shim::GetStorage();
bluetooth::hci::Address address = ToGdAddress(bd_addr);
diff --git a/system/main/shim/stack.h b/system/main/shim/stack.h
index b105866b18..f32db434a1 100644
--- a/system/main/shim/stack.h
+++ b/system/main/shim/stack.h
@@ -39,6 +39,9 @@ class Stack {
static Stack* GetInstance();
Stack() = default;
+ Stack(const Stack&) = delete;
+ Stack& operator=(const Stack&) = delete;
+
~Stack() = default;
// Idle mode, config is loaded, but controller is not enabled
@@ -64,8 +67,6 @@ class Stack {
return rust_controller_;
}
- DISALLOW_COPY_AND_ASSIGN(Stack);
-
private:
mutable std::recursive_mutex mutex_;
StackManager stack_manager_;
diff --git a/system/packet/avrcp/avrcp_browse_packet.h b/system/packet/avrcp/avrcp_browse_packet.h
index 038f576426..f6bd72e225 100644
--- a/system/packet/avrcp/avrcp_browse_packet.h
+++ b/system/packet/avrcp/avrcp_browse_packet.h
@@ -17,7 +17,6 @@
#pragma once
#include <base/logging.h>
-#include <base/macros.h>
#include <iostream>
#include "hardware/avrcp/avrcp_common.h"
@@ -52,6 +51,9 @@ class BrowsePacketBuilder : public ::bluetooth::PacketBuilder {
class BrowsePacket : public ::bluetooth::Packet {
public:
+ BrowsePacket(const BrowsePacket&) = delete;
+ BrowsePacket& operator=(const BrowsePacket&) = delete;
+
virtual ~BrowsePacket() = default;
static std::shared_ptr<BrowsePacket> Parse(
@@ -76,8 +78,7 @@ class BrowsePacket : public ::bluetooth::Packet {
private:
virtual std::pair<size_t, size_t> GetPayloadIndecies() const override;
- DISALLOW_COPY_AND_ASSIGN(BrowsePacket);
};
} // namespace avrcp
-} // namespace bluetooth \ No newline at end of file
+} // namespace bluetooth
diff --git a/system/packet/avrcp/avrcp_packet.h b/system/packet/avrcp/avrcp_packet.h
index ee0e0d5ad1..7a44dc57bb 100644
--- a/system/packet/avrcp/avrcp_packet.h
+++ b/system/packet/avrcp/avrcp_packet.h
@@ -17,7 +17,6 @@
#pragma once
#include <base/logging.h>
-#include <base/macros.h>
#include <iostream>
#include "hardware/avrcp/avrcp_common.h"
@@ -62,6 +61,9 @@ class PacketBuilder : public ::bluetooth::PacketBuilder {
class Packet : public ::bluetooth::Packet {
public:
+ Packet(const Packet&) = delete;
+ Packet& operator=(const Packet&) = delete;
+
virtual ~Packet() = default;
// TODO (apanicke): Right now we can use this to build an AvrcpPacket from
@@ -104,7 +106,6 @@ class Packet : public ::bluetooth::Packet {
private:
virtual std::pair<size_t, size_t> GetPayloadIndecies() const override;
- DISALLOW_COPY_AND_ASSIGN(Packet);
};
} // namespace avrcp
diff --git a/system/profile/avrcp/connection_handler.h b/system/profile/avrcp/connection_handler.h
index 5320b63a47..67445a8df5 100644
--- a/system/profile/avrcp/connection_handler.h
+++ b/system/profile/avrcp/connection_handler.h
@@ -158,6 +158,9 @@ class ConnectionHandler {
tAVRC_MSG* p_msg);
ConnectionHandler() : weak_ptr_factory_(this){};
+ ConnectionHandler(const ConnectionHandler&) = delete;
+ ConnectionHandler& operator=(const ConnectionHandler&) = delete;
+
virtual ~ConnectionHandler() = default;
// Callback for when sending a response to a device
@@ -165,7 +168,6 @@ class ConnectionHandler {
std::unique_ptr<::bluetooth::PacketBuilder> message);
base::WeakPtrFactory<ConnectionHandler> weak_ptr_factory_;
- DISALLOW_COPY_AND_ASSIGN(ConnectionHandler);
};
} // namespace avrcp
diff --git a/system/profile/avrcp/device.h b/system/profile/avrcp/device.h
index fc5d7364b0..07e1cac7d2 100644
--- a/system/profile/avrcp/device.h
+++ b/system/profile/avrcp/device.h
@@ -65,6 +65,10 @@ class Device {
std::unique_ptr<::bluetooth::PacketBuilder> message)>
send_msg_cb,
uint16_t ctrl_mtu, uint16_t browse_mtu);
+
+ Device(const Device&) = delete;
+ Device& operator=(const Device&) = delete;
+
virtual ~Device() = default;
/**
@@ -339,7 +343,6 @@ class Device {
std::set<uint8_t> active_labels_;
int8_t volume_ = -1;
- DISALLOW_COPY_AND_ASSIGN(Device);
};
} // namespace avrcp
diff --git a/system/service/a2dp_sink.h b/system/service/a2dp_sink.h
index 7bf59026ac..7b6f3ce7e0 100644
--- a/system/service/a2dp_sink.h
+++ b/system/service/a2dp_sink.h
@@ -16,8 +16,6 @@
#pragma once
-#include <base/macros.h>
-
#include <atomic>
#include <mutex>
#include <string>
@@ -47,6 +45,9 @@ class A2dpSink : public BluetoothInstance,
virtual ~Delegate() = default;
};
+ A2dpSink(const A2dpSink&) = delete;
+ A2dpSink& operator=(const A2dpSink&) = delete;
+
~A2dpSink() override;
void SetDelegate(Delegate* delegate);
@@ -84,21 +85,19 @@ class A2dpSink : public BluetoothInstance,
std::mutex mutex_;
std::mutex delegate_mutex_;
Delegate* delegate_ = nullptr;
-
- DISALLOW_COPY_AND_ASSIGN(A2dpSink);
};
class A2dpSinkFactory : public BluetoothInstanceFactory {
public:
A2dpSinkFactory();
+ A2dpSinkFactory(const A2dpSinkFactory&) = delete;
+ A2dpSinkFactory& operator=(const A2dpSinkFactory&) = delete;
+
~A2dpSinkFactory() override;
// BluetoothInstanceFactory override:
bool RegisterInstance(const Uuid& uuid,
const RegisterCallback& callback) override;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(A2dpSinkFactory);
};
} // namespace bluetooth
diff --git a/system/service/a2dp_source.h b/system/service/a2dp_source.h
index 801393f4d1..5b1b554606 100644
--- a/system/service/a2dp_source.h
+++ b/system/service/a2dp_source.h
@@ -16,8 +16,6 @@
#pragma once
-#include <base/macros.h>
-
#include <atomic>
#include <mutex>
#include <string>
@@ -50,6 +48,9 @@ class A2dpSource : public BluetoothInstance,
virtual ~Delegate() = default;
};
+ A2dpSource(const A2dpSource&) = delete;
+ A2dpSource& operator=(const A2dpSource&) = delete;
+
~A2dpSource() override;
void SetDelegate(Delegate* delegate);
@@ -99,21 +100,19 @@ class A2dpSource : public BluetoothInstance,
// delegate function which attempts to take 'clock'.
std::mutex delegate_mutex_;
Delegate* delegate_ = nullptr;
-
- DISALLOW_COPY_AND_ASSIGN(A2dpSource);
};
class A2dpSourceFactory : public BluetoothInstanceFactory {
public:
A2dpSourceFactory();
+ A2dpSourceFactory(const A2dpSourceFactory&) = delete;
+ A2dpSourceFactory& operator=(const A2dpSourceFactory&) = delete;
+
~A2dpSourceFactory() override;
// BluetoothInstanceFactory override:
bool RegisterInstance(const Uuid& uuid,
const RegisterCallback& callback) override;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(A2dpSourceFactory);
};
} // namespace bluetooth
diff --git a/system/service/adapter.cc b/system/service/adapter.cc
index 9c0468899a..19e7400a62 100644
--- a/system/service/adapter.cc
+++ b/system/service/adapter.cc
@@ -215,6 +215,9 @@ class AdapterImpl : public Adapter, public hal::BluetoothInterface::Observer {
hal::BluetoothInterface::Get()->GetHALInterface()->get_adapter_properties();
}
+ AdapterImpl(const AdapterImpl&) = delete;
+ AdapterImpl& operator=(const AdapterImpl&) = delete;
+
~AdapterImpl() override {
hal::BluetoothInterface::Get()->RemoveObserver(this);
}
@@ -800,8 +803,6 @@ class AdapterImpl : public Adapter, public hal::BluetoothInterface::Observer {
// Factory used to create per-app GattServer instances.
std::unique_ptr<GattServerFactory> gatt_server_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(AdapterImpl);
};
// static
diff --git a/system/service/adapter.h b/system/service/adapter.h
index a4e517c2cc..e3fa306cf1 100644
--- a/system/service/adapter.h
+++ b/system/service/adapter.h
@@ -20,8 +20,6 @@
#include <string>
#include <vector>
-#include <base/macros.h>
-
#include "service/common/bluetooth/adapter_state.h"
#include "service/common/bluetooth/remote_device_props.h"
@@ -102,6 +100,9 @@ class Adapter {
// in tests; use MockAdapter instead.
static std::unique_ptr<Adapter> Create();
+ Adapter(const Adapter&) = delete;
+ Adapter& operator=(const Adapter&) = delete;
+
virtual ~Adapter() = default;
// Add or remove an observer.
@@ -221,9 +222,6 @@ class Adapter {
protected:
Adapter() = default;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Adapter);
};
} // namespace bluetooth
diff --git a/system/service/avrcp_control.h b/system/service/avrcp_control.h
index eef36f8927..47950e335d 100644
--- a/system/service/avrcp_control.h
+++ b/system/service/avrcp_control.h
@@ -19,7 +19,6 @@
#include <atomic>
#include <mutex>
-#include "base/macros.h"
#include "bluetooth/uuid.h"
#include "service/bluetooth_instance.h"
#include "service/common/bluetooth/avrcp_media_attr.h"
@@ -50,6 +49,9 @@ class AvrcpControl : public BluetoothInstance,
virtual ~Delegate() = default;
};
+ AvrcpControl(const AvrcpControl&) = delete;
+ AvrcpControl& operator=(const AvrcpControl&) = delete;
+
// The destructor automatically unregisters this instance from the stack.
~AvrcpControl() override;
@@ -106,8 +108,6 @@ class AvrcpControl : public BluetoothInstance,
// Raw handle to the Delegate, which must outlive this AvrcpControl instance.
std::mutex delegate_mutex_;
Delegate* delegate_ = nullptr;
-
- DISALLOW_COPY_AND_ASSIGN(AvrcpControl);
};
// AvrcpControlFactory is used to register and obtain a per-application
@@ -121,6 +121,9 @@ class AvrcpControlFactory
// Don't construct/destruct directly except in tests. Instead, obtain a handle
// from an Adapter instance.
AvrcpControlFactory();
+ AvrcpControlFactory(const AvrcpControlFactory&) = delete;
+ AvrcpControlFactory& operator=(const AvrcpControlFactory&) = delete;
+
~AvrcpControlFactory() override;
// BluetoothInstanceFactory override:
@@ -129,7 +132,6 @@ class AvrcpControlFactory
private:
std::atomic<int> next_control_id_{0};
- DISALLOW_COPY_AND_ASSIGN(AvrcpControlFactory);
};
} // namespace bluetooth
diff --git a/system/service/avrcp_target.cc b/system/service/avrcp_target.cc
index f5d21b72a5..9a39b412f4 100644
--- a/system/service/avrcp_target.cc
+++ b/system/service/avrcp_target.cc
@@ -23,7 +23,6 @@
#include "array_utils.h"
#include "base/logging.h"
-#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "service/logging_helpers.h"
#include "stack/include/avrc_defs.h"
diff --git a/system/service/avrcp_target.h b/system/service/avrcp_target.h
index e0ee57bb5a..76c5be0db8 100644
--- a/system/service/avrcp_target.h
+++ b/system/service/avrcp_target.h
@@ -20,7 +20,6 @@
#include <string>
#include <vector>
-#include "base/macros.h"
#include "service/bluetooth_instance.h"
#include "service/common/bluetooth/avrcp_int_value.h"
#include "service/common/bluetooth/avrcp_register_notification_response.h"
@@ -68,6 +67,9 @@ class AvrcpTarget : public BluetoothInstance,
virtual ~Delegate() = default;
};
+ AvrcpTarget(const AvrcpTarget&) = delete;
+ AvrcpTarget& operator=(const AvrcpTarget&) = delete;
+
// The destructor automatically unregisters this instance from the stack.
~AvrcpTarget() override;
@@ -150,8 +152,6 @@ class AvrcpTarget : public BluetoothInstance,
// Raw handle to the Delegate, which must outlive this AvrcpTarget instance.
std::mutex delegate_mutex_;
Delegate* delegate_ = nullptr;
-
- DISALLOW_COPY_AND_ASSIGN(AvrcpTarget);
};
// AvrcpTargetFactory is used to register and obtain a per-application
@@ -165,14 +165,14 @@ class AvrcpTargetFactory
// Don't construct/destruct directly except in tests. Instead, obtain a handle
// from an Adapter instance.
AvrcpTargetFactory();
+ AvrcpTargetFactory(const AvrcpTargetFactory&) = delete;
+ AvrcpTargetFactory& operator=(const AvrcpTargetFactory&) = delete;
+
~AvrcpTargetFactory() override;
// BluetoothInstanceFactory override:
bool RegisterInstance(const Uuid& uuid,
const RegisterCallback& callback) override;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(AvrcpTargetFactory);
};
} // namespace bluetooth
diff --git a/system/service/bluetooth_instance.h b/system/service/bluetooth_instance.h
index d0146c585a..5728d5e02b 100644
--- a/system/service/bluetooth_instance.h
+++ b/system/service/bluetooth_instance.h
@@ -19,7 +19,6 @@
#include <functional>
#include <memory>
-#include <base/macros.h>
#include <bluetooth/uuid.h>
#include "service/common/bluetooth/low_energy_constants.h"
@@ -31,6 +30,9 @@ namespace bluetooth {
// stack-assigned integer "instance_id" ID associated with it.
class BluetoothInstance {
public:
+ BluetoothInstance(const BluetoothInstance&) = delete;
+ BluetoothInstance& operator=(const BluetoothInstance&) = delete;
+
virtual ~BluetoothInstance() = default;
// Returns the app-specific unique ID used while registering this instance.
@@ -43,9 +45,6 @@ class BluetoothInstance {
// Constructor shouldn't be called directly as instances are meant to be
// obtained from the factory.
BluetoothInstance() = default;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(BluetoothInstance);
};
// A BluetoothInstanceFactory provides a common interface for factory
@@ -54,6 +53,9 @@ class BluetoothInstance {
class BluetoothInstanceFactory {
public:
BluetoothInstanceFactory() = default;
+ BluetoothInstanceFactory(const BluetoothInstanceFactory&) = delete;
+ BluetoothInstanceFactory& operator=(const BluetoothInstanceFactory&) = delete;
+
virtual ~BluetoothInstanceFactory() = default;
// Callback invoked as a result of a call to RegisterInstance.
@@ -67,9 +69,6 @@ class BluetoothInstanceFactory {
// the case of an error, the pointer will contain nullptr.
virtual bool RegisterInstance(const Uuid& app_uuid,
const RegisterCallback& callback) = 0;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(BluetoothInstanceFactory);
};
} // namespace bluetooth
diff --git a/system/service/bluetooth_interface.cc b/system/service/bluetooth_interface.cc
index aafa04fa3f..1c178bdc00 100644
--- a/system/service/bluetooth_interface.cc
+++ b/system/service/bluetooth_interface.cc
@@ -239,7 +239,7 @@ static int set_adapter_property(const bt_property_t* property) {
switch (property->type) {
case BT_PROPERTY_BDNAME:
case BT_PROPERTY_ADAPTER_SCAN_MODE:
- case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
+ case BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT:
case BT_PROPERTY_CLASS_OF_DEVICE:
case BT_PROPERTY_LOCAL_IO_CAPS:
case BT_PROPERTY_LOCAL_IO_CAPS_BLE:
diff --git a/system/service/client/main.cc b/system/service/client/main.cc
index b4ab06e382..b08136997a 100644
--- a/system/service/client/main.cc
+++ b/system/service/client/main.cc
@@ -20,7 +20,6 @@
#include <base/at_exit.h>
#include <base/command_line.h>
#include <base/logging.h>
-#include <base/macros.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>
@@ -147,6 +146,8 @@ inline void EndAsyncOut() {
class CLIBluetoothCallback : public android::bluetooth::BnBluetoothCallback {
public:
CLIBluetoothCallback() = default;
+ CLIBluetoothCallback(const CLIBluetoothCallback&) = delete;
+ CLIBluetoothCallback& operator=(const CLIBluetoothCallback&) = delete;
~CLIBluetoothCallback() override = default;
// IBluetoothCallback overrides:
@@ -216,15 +217,15 @@ class CLIBluetoothCallback : public android::bluetooth::BnBluetoothCallback {
// no-op
return Status::ok();
}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(CLIBluetoothCallback);
};
class CLIBluetoothLowEnergyCallback
: public android::bluetooth::BnBluetoothLowEnergyCallback {
public:
CLIBluetoothLowEnergyCallback() = default;
+ CLIBluetoothLowEnergyCallback(const CLIBluetoothLowEnergyCallback&) = delete;
+ CLIBluetoothLowEnergyCallback& operator=(
+ const CLIBluetoothLowEnergyCallback&) = delete;
~CLIBluetoothLowEnergyCallback() override = default;
// IBluetoothLowEnergyCallback overrides:
@@ -262,15 +263,16 @@ class CLIBluetoothLowEnergyCallback
EndAsyncOut();
return Status::ok();
}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(CLIBluetoothLowEnergyCallback);
};
class CLIBluetoothLeAdvertiserCallback
: public android::bluetooth::BnBluetoothLeAdvertiserCallback {
public:
CLIBluetoothLeAdvertiserCallback() = default;
+ CLIBluetoothLeAdvertiserCallback(const CLIBluetoothLeAdvertiserCallback&) =
+ delete;
+ CLIBluetoothLeAdvertiserCallback& operator=(
+ const CLIBluetoothLeAdvertiserCallback&) = delete;
~CLIBluetoothLeAdvertiserCallback() override = default;
// IBluetoothLowEnergyCallback overrides:
@@ -299,15 +301,15 @@ class CLIBluetoothLeAdvertiserCallback
EndAsyncOut();
return Status::ok();
}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(CLIBluetoothLeAdvertiserCallback);
};
class CLIBluetoothLeScannerCallback
: public android::bluetooth::BnBluetoothLeScannerCallback {
public:
CLIBluetoothLeScannerCallback() = default;
+ CLIBluetoothLeScannerCallback(const CLIBluetoothLeScannerCallback&) = delete;
+ CLIBluetoothLeScannerCallback& operator=(
+ const CLIBluetoothLeScannerCallback&) = delete;
~CLIBluetoothLeScannerCallback() override = default;
// IBluetoothLowEnergyCallback overrides:
@@ -341,15 +343,14 @@ class CLIBluetoothLeScannerCallback
EndAsyncOut();
return Status::ok();
}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(CLIBluetoothLeScannerCallback);
};
class CLIGattClientCallback
: public android::bluetooth::BnBluetoothGattClientCallback {
public:
CLIGattClientCallback() = default;
+ CLIGattClientCallback(const CLIGattClientCallback&) = delete;
+ CLIGattClientCallback& operator=(const CLIGattClientCallback&) = delete;
~CLIGattClientCallback() override = default;
// IBluetoothGattClientCallback overrides:
@@ -367,9 +368,6 @@ class CLIGattClientCallback
gatt_registering = false;
return Status::ok();
}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(CLIGattClientCallback);
};
void PrintCommandStatus(bool status) { PrintOpStatus("Command", status); }
@@ -1051,6 +1049,8 @@ bool ExecuteCommand(const sp<IBluetooth>& bt_iface, std::string& command) {
class BluetoothDeathRecipient : public android::IBinder::DeathRecipient {
public:
BluetoothDeathRecipient() = default;
+ BluetoothDeathRecipient(const BluetoothDeathRecipient&) = delete;
+ BluetoothDeathRecipient& operator=(const BluetoothDeathRecipient&) = delete;
~BluetoothDeathRecipient() override = default;
// android::IBinder::DeathRecipient override:
@@ -1063,9 +1063,6 @@ class BluetoothDeathRecipient : public android::IBinder::DeathRecipient {
android::IPCThreadState::self()->stopProcess();
should_exit = true;
}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(BluetoothDeathRecipient);
};
int main(int argc, char* argv[]) {
diff --git a/system/service/common/bluetooth/advertise_data.h b/system/service/common/bluetooth/advertise_data.h
index bae83ee334..796f7dcc15 100644
--- a/system/service/common/bluetooth/advertise_data.h
+++ b/system/service/common/bluetooth/advertise_data.h
@@ -20,8 +20,6 @@
#include <vector>
-#include <base/macros.h>
-
namespace bluetooth {
// Represents a data packet for Bluetooth Low Energy advertisements. This is the
diff --git a/system/service/common/bluetooth/advertise_settings.h b/system/service/common/bluetooth/advertise_settings.h
index 4aff4c92dd..e4aee5377a 100644
--- a/system/service/common/bluetooth/advertise_settings.h
+++ b/system/service/common/bluetooth/advertise_settings.h
@@ -16,7 +16,6 @@
#pragma once
-#include <base/macros.h>
#include <base/time/time.h>
namespace bluetooth {
diff --git a/system/service/common/bluetooth/util/atomic_string.h b/system/service/common/bluetooth/util/atomic_string.h
index 46d4588ed2..f5ed1c3ba4 100644
--- a/system/service/common/bluetooth/util/atomic_string.h
+++ b/system/service/common/bluetooth/util/atomic_string.h
@@ -19,14 +19,16 @@
#include <mutex>
#include <string>
-#include <base/macros.h>
-
namespace util {
// A simple atomic container class for std::string.
class AtomicString final {
public:
explicit AtomicString(const std::string& str);
+
+ AtomicString(const AtomicString&) = delete;
+ AtomicString& operator=(const AtomicString&) = delete;
+
~AtomicString() = default;
std::string Get() const;
@@ -35,8 +37,6 @@ class AtomicString final {
private:
std::mutex lock_;
std::string str_;
-
- DISALLOW_COPY_AND_ASSIGN(AtomicString);
};
} // namespace util
diff --git a/system/service/daemon.cc b/system/service/daemon.cc
index 4cd384285b..11bfae1722 100644
--- a/system/service/daemon.cc
+++ b/system/service/daemon.cc
@@ -42,6 +42,9 @@ class DaemonImpl : public Daemon, public ipc::IPCManager::Delegate {
public:
DaemonImpl() : initialized_(false) {}
+ DaemonImpl(const DaemonImpl&) = delete;
+ DaemonImpl& operator=(const DaemonImpl&) = delete;
+
~DaemonImpl() override {
if (!initialized_) return;
@@ -161,8 +164,6 @@ class DaemonImpl : public Daemon, public ipc::IPCManager::Delegate {
std::unique_ptr<Settings> settings_;
std::unique_ptr<Adapter> adapter_;
std::unique_ptr<ipc::IPCManager> ipc_manager_;
-
- DISALLOW_COPY_AND_ASSIGN(DaemonImpl);
};
} // namespace
diff --git a/system/service/daemon.h b/system/service/daemon.h
index 06afe91008..a1f26a07e2 100644
--- a/system/service/daemon.h
+++ b/system/service/daemon.h
@@ -16,7 +16,6 @@
#pragma once
-#include <base/macros.h>
#include "abstract_message_loop.h"
namespace ipc {
@@ -62,13 +61,14 @@ class Daemon {
protected:
Daemon() = default;
+ Daemon(const Daemon&) = delete;
+ Daemon& operator=(const Daemon&) = delete;
+
virtual ~Daemon() = default;
private:
// Internal instance helper called by Initialize().
virtual bool Init() = 0;
-
- DISALLOW_COPY_AND_ASSIGN(Daemon);
};
} // namespace bluetooth
diff --git a/system/service/example/heart_rate/heart_rate_server.cc b/system/service/example/heart_rate/heart_rate_server.cc
index 170042a70f..9777c203f8 100644
--- a/system/service/example/heart_rate/heart_rate_server.cc
+++ b/system/service/example/heart_rate/heart_rate_server.cc
@@ -41,6 +41,11 @@ class CLIBluetoothLeAdvertiserCallback
android::sp<android::bluetooth::IBluetooth> bt)
: bt_(bt) {}
+ CLIBluetoothLeAdvertiserCallback(const CLIBluetoothLeAdvertiserCallback&) =
+ delete;
+ CLIBluetoothLeAdvertiserCallback& operator=(
+ const CLIBluetoothLeAdvertiserCallback&) = delete;
+
// IBluetoothLeAdvertiserCallback overrides:
Status OnAdvertiserRegistered(int status, int advertiser_id) {
if (status != bluetooth::BLE_STATUS_SUCCESS) {
@@ -90,7 +95,6 @@ class CLIBluetoothLeAdvertiserCallback
private:
android::sp<android::bluetooth::IBluetooth> bt_;
- DISALLOW_COPY_AND_ASSIGN(CLIBluetoothLeAdvertiserCallback);
};
HeartRateServer::HeartRateServer(
diff --git a/system/service/example/heart_rate/heart_rate_server.h b/system/service/example/heart_rate/heart_rate_server.h
index e78c58aecf..1b716fd193 100644
--- a/system/service/example/heart_rate/heart_rate_server.h
+++ b/system/service/example/heart_rate/heart_rate_server.h
@@ -19,7 +19,6 @@
#include <mutex>
#include <unordered_map>
-#include <base/macros.h>
#include <base/memory/ref_counted.h>
#include <base/memory/weak_ptr.h>
#if BASE_VER < 930627
@@ -44,6 +43,9 @@ class HeartRateServer
HeartRateServer(android::sp<android::bluetooth::IBluetooth> bluetooth,
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
bool advertise);
+ HeartRateServer(const HeartRateServer&) = delete;
+ HeartRateServer& operator=(const HeartRateServer&) = delete;
+
~HeartRateServer() override;
// Set up the server and register the GATT services with the stack. This
@@ -141,8 +143,6 @@ class HeartRateServer
// Note: This should remain the last member so that it'll be destroyed and
// invalidate its weak pointers before any other members are destroyed.
base::WeakPtrFactory<HeartRateServer> weak_ptr_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(HeartRateServer);
};
} // namespace heart_rate
diff --git a/system/service/gatt_client.h b/system/service/gatt_client.h
index 5a0322d2da..4ed1143e4e 100644
--- a/system/service/gatt_client.h
+++ b/system/service/gatt_client.h
@@ -19,7 +19,6 @@
#include <mutex>
#include <unordered_map>
-#include <base/macros.h>
#include <bluetooth/uuid.h>
#include "service/bluetooth_instance.h"
@@ -32,6 +31,9 @@ namespace bluetooth {
// obtained through the factory.
class GattClient : public BluetoothInstance {
public:
+ GattClient(const GattClient&) = delete;
+ GattClient& operator=(const GattClient&) = delete;
+
~GattClient() override;
// BluetoothClientInstace overrides:
@@ -48,8 +50,6 @@ class GattClient : public BluetoothInstance {
// See getters above for documentation.
Uuid app_identifier_;
int client_id_;
-
- DISALLOW_COPY_AND_ASSIGN(GattClient);
};
// GattClientFactory is used to register and obtain a per-application GattClient
@@ -61,6 +61,9 @@ class GattClientFactory : public BluetoothInstanceFactory,
// Don't construct/destruct directly except in tests. Instead, obtain a handle
// from an Adapter instance.
GattClientFactory();
+ GattClientFactory(const GattClientFactory&) = delete;
+ GattClientFactory& operator=(const GattClientFactory&) = delete;
+
~GattClientFactory() override;
// BluetoothInstanceFactory override:
@@ -76,8 +79,6 @@ class GattClientFactory : public BluetoothInstanceFactory,
// Map of pending calls to register.
std::mutex pending_calls_lock_;
std::unordered_map<Uuid, RegisterCallback> pending_calls_;
-
- DISALLOW_COPY_AND_ASSIGN(GattClientFactory);
};
} // namespace bluetooth
diff --git a/system/service/gatt_server.h b/system/service/gatt_server.h
index c46e8d00c4..7d670aed91 100644
--- a/system/service/gatt_server.h
+++ b/system/service/gatt_server.h
@@ -16,7 +16,6 @@
#pragma once
-#include <base/macros.h>
#include <bluetooth/uuid.h>
#include <deque>
@@ -45,6 +44,9 @@ class GattServer : public BluetoothInstance,
class Delegate {
public:
Delegate() = default;
+ Delegate(const Delegate&) = delete;
+ Delegate& operator=(const Delegate&) = delete;
+
virtual ~Delegate() = default;
// Called when there is an incoming read request for the characteristic with
@@ -104,12 +106,12 @@ class GattServer : public BluetoothInstance,
virtual void OnConnectionStateChanged(GattServer* gatt_server,
const std::string& device_addres,
bool connected) = 0;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Delegate);
};
// The desctructor automatically unregisters this instance from the stack.
+ GattServer(const GattServer&) = delete;
+ GattServer& operator=(const GattServer&) = delete;
+
~GattServer() override;
// Assigns a delegate to this instance. |delegate| must out-live this
@@ -262,8 +264,6 @@ class GattServer : public BluetoothInstance,
// Raw handle to the Delegate, which must outlive this GattServer instance.
Delegate* delegate_;
-
- DISALLOW_COPY_AND_ASSIGN(GattServer);
};
// GattServerFactory is used to register and obtain a per-application GattServer
@@ -275,6 +275,9 @@ class GattServerFactory : public BluetoothInstanceFactory,
// Don't construct/destruct directly except in tests. Instead, obtain a handle
// from an Adapter instance.
GattServerFactory();
+ GattServerFactory(const GattServerFactory&) = delete;
+ GattServerFactory& operator=(const GattServerFactory&) = delete;
+
~GattServerFactory() override;
// BluetoothInstanceFactory override:
@@ -290,8 +293,6 @@ class GattServerFactory : public BluetoothInstanceFactory,
// Map of pending calls to register.
std::mutex pending_calls_lock_;
std::unordered_map<Uuid, RegisterCallback> pending_calls_;
-
- DISALLOW_COPY_AND_ASSIGN(GattServerFactory);
};
} // namespace bluetooth
diff --git a/system/service/hal/bluetooth_av_interface.cc b/system/service/hal/bluetooth_av_interface.cc
index e4a759dd9f..beabd968f2 100644
--- a/system/service/hal/bluetooth_av_interface.cc
+++ b/system/service/hal/bluetooth_av_interface.cc
@@ -147,6 +147,9 @@ btav_sink_callbacks_t av_sink_callbacks = {
class BluetoothAvInterfaceImpl : public BluetoothAvInterface {
public:
BluetoothAvInterfaceImpl() = default;
+ BluetoothAvInterfaceImpl(const BluetoothAvInterfaceImpl&) = delete;
+ BluetoothAvInterfaceImpl& operator=(const BluetoothAvInterfaceImpl&) = delete;
+
~BluetoothAvInterfaceImpl() override {
A2dpSinkDisable();
A2dpSourceDisable();
@@ -274,8 +277,6 @@ class BluetoothAvInterfaceImpl : public BluetoothAvInterface {
bool source_enabled_ = false;
bool sink_enabled_ = false;
-
- DISALLOW_COPY_AND_ASSIGN(BluetoothAvInterfaceImpl);
};
namespace {
diff --git a/system/service/hal/bluetooth_av_interface.h b/system/service/hal/bluetooth_av_interface.h
index 2b444b2b67..4f0b4773e8 100644
--- a/system/service/hal/bluetooth_av_interface.h
+++ b/system/service/hal/bluetooth_av_interface.h
@@ -16,7 +16,6 @@
#pragma once
-#include <base/macros.h>
#include <hardware/bluetooth.h>
#include <hardware/bt_av.h>
@@ -90,10 +89,10 @@ class BluetoothAvInterface {
protected:
BluetoothAvInterface() = default;
- virtual ~BluetoothAvInterface() = default;
+ BluetoothAvInterface(const BluetoothAvInterface&) = delete;
+ BluetoothAvInterface& operator=(const BluetoothAvInterface&) = delete;
- private:
- DISALLOW_COPY_AND_ASSIGN(BluetoothAvInterface);
+ virtual ~BluetoothAvInterface() = default;
};
} // namespace hal
diff --git a/system/service/hal/bluetooth_avrcp_interface.cc b/system/service/hal/bluetooth_avrcp_interface.cc
index 42ac0a6372..cbb0317041 100644
--- a/system/service/hal/bluetooth_avrcp_interface.cc
+++ b/system/service/hal/bluetooth_avrcp_interface.cc
@@ -490,6 +490,10 @@ class BluetoothAvrcpInterfaceImpl : public BluetoothAvrcpInterface {
public:
BluetoothAvrcpInterfaceImpl() : control_iface_(nullptr) {}
+ BluetoothAvrcpInterfaceImpl(const BluetoothAvrcpInterfaceImpl&) = delete;
+ BluetoothAvrcpInterfaceImpl& operator=(const BluetoothAvrcpInterfaceImpl&) =
+ delete;
+
~BluetoothAvrcpInterfaceImpl() override {
if (control_iface_) control_iface_->cleanup();
}
@@ -614,8 +618,6 @@ class BluetoothAvrcpInterfaceImpl : public BluetoothAvrcpInterface {
bool control_enabled_ = false;
bool target_enabled_ = false;
-
- DISALLOW_COPY_AND_ASSIGN(BluetoothAvrcpInterfaceImpl);
};
namespace {
diff --git a/system/service/hal/bluetooth_avrcp_interface.h b/system/service/hal/bluetooth_avrcp_interface.h
index fc67c3c41f..4646880169 100644
--- a/system/service/hal/bluetooth_avrcp_interface.h
+++ b/system/service/hal/bluetooth_avrcp_interface.h
@@ -16,7 +16,6 @@
#pragma once
-#include <base/macros.h>
#include <hardware/bluetooth.h>
#include <hardware/bt_rc.h>
@@ -130,6 +129,9 @@ class BluetoothAvrcpInterface {
uint8_t status);
};
+ BluetoothAvrcpInterface(const BluetoothAvrcpInterface&) = delete;
+ BluetoothAvrcpInterface& operator=(const BluetoothAvrcpInterface&) = delete;
+
// Initialize and clean up the BluetoothInterface singleton. Returns false if
// the underlying HAL interface failed to initialize, and true on success.
static bool Initialize();
@@ -172,9 +174,6 @@ class BluetoothAvrcpInterface {
protected:
BluetoothAvrcpInterface() = default;
virtual ~BluetoothAvrcpInterface() = default;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(BluetoothAvrcpInterface);
};
} // namespace hal
diff --git a/system/service/hal/bluetooth_gatt_interface.cc b/system/service/hal/bluetooth_gatt_interface.cc
index c9d165b0c3..76cf5c9361 100644
--- a/system/service/hal/bluetooth_gatt_interface.cc
+++ b/system/service/hal/bluetooth_gatt_interface.cc
@@ -443,6 +443,10 @@ class BluetoothGattInterfaceImpl : public BluetoothGattInterface {
public:
BluetoothGattInterfaceImpl() : hal_iface_(nullptr) {}
+ BluetoothGattInterfaceImpl(const BluetoothGattInterfaceImpl&) = delete;
+ BluetoothGattInterfaceImpl& operator=(const BluetoothGattInterfaceImpl&) =
+ delete;
+
~BluetoothGattInterfaceImpl() override {
if (hal_iface_) hal_iface_->cleanup();
}
@@ -536,8 +540,6 @@ class BluetoothGattInterfaceImpl : public BluetoothGattInterface {
// The HAL handle obtained from the shared library. We hold a weak reference
// to this since the actual data resides in the shared Bluetooth library.
const btgatt_interface_t* hal_iface_;
-
- DISALLOW_COPY_AND_ASSIGN(BluetoothGattInterfaceImpl);
};
namespace {
diff --git a/system/service/hal/bluetooth_gatt_interface.h b/system/service/hal/bluetooth_gatt_interface.h
index 471dfc4d03..ad3f851554 100644
--- a/system/service/hal/bluetooth_gatt_interface.h
+++ b/system/service/hal/bluetooth_gatt_interface.h
@@ -16,7 +16,6 @@
#pragma once
-#include <base/macros.h>
#include <hardware/bluetooth.h>
#include <hardware/bt_gatt.h>
@@ -254,14 +253,15 @@ class BluetoothGattInterface {
protected:
BluetoothGattInterface() = default;
+ BluetoothGattInterface(const BluetoothGattInterface&) = delete;
+ BluetoothGattInterface& operator=(const BluetoothGattInterface&) = delete;
+
virtual ~BluetoothGattInterface() = default;
private:
// Used to keep a reference count for the different BLE scan clients.
std::mutex scan_clients_lock_;
std::unordered_set<int> scan_client_set_;
-
- DISALLOW_COPY_AND_ASSIGN(BluetoothGattInterface);
};
} // namespace hal
diff --git a/system/service/hal/bluetooth_interface.cc b/system/service/hal/bluetooth_interface.cc
index c47a3edf35..3acb5725d0 100644
--- a/system/service/hal/bluetooth_interface.cc
+++ b/system/service/hal/bluetooth_interface.cc
@@ -217,14 +217,13 @@ void LinkQualityReportCallback(uint64_t timestamp, int report_id, int rssi,
packets_not_receive_count, negative_acknowledgement_count));
}
-void SwitchBufferSizeCallback(RawAddress* remote_addr,
- bool is_low_latency_buffer_size) {
+void SwitchBufferSizeCallback(bool is_low_latency_buffer_size) {
shared_lock<shared_mutex_impl> lock(g_instance_lock);
VERIFY_INTERFACE_OR_RETURN();
LOG(WARNING) << __func__ << " - is_low_latency_buffer_size: "
<< is_low_latency_buffer_size;
FOR_EACH_BLUETOOTH_OBSERVER(
- SwitchBufferSizeCallback(remote_addr, is_low_latency_buffer_size));
+ SwitchBufferSizeCallback(is_low_latency_buffer_size));
}
// The HAL Bluetooth DM callbacks.
@@ -246,7 +245,7 @@ bt_callbacks_t bt_callbacks = {
nullptr, /* energy_info_cb */
LinkQualityReportCallback,
nullptr /* generate_local_oob_data_cb */,
- SwitchBufferSizeCallback
+ SwitchBufferSizeCallback,
};
bt_os_callouts_t bt_os_callouts = {sizeof(bt_os_callouts_t),
@@ -297,6 +296,9 @@ class BluetoothInterfaceImpl : public BluetoothInterface {
public:
BluetoothInterfaceImpl() : hal_iface_(nullptr) {}
+ BluetoothInterfaceImpl(const BluetoothInterfaceImpl&) = delete;
+ BluetoothInterfaceImpl& operator=(const BluetoothInterfaceImpl&) = delete;
+
~BluetoothInterfaceImpl() override {
if (hal_iface_) hal_iface_->cleanup();
}
@@ -358,8 +360,6 @@ class BluetoothInterfaceImpl : public BluetoothInterface {
// The HAL handle obtained from the shared library. We hold a weak reference
// to this since the actual data resides in the shared Bluetooth library.
const bt_interface_t* hal_iface_;
-
- DISALLOW_COPY_AND_ASSIGN(BluetoothInterfaceImpl);
};
namespace {
@@ -437,7 +437,7 @@ void BluetoothInterface::Observer::LinkQualityReportCallback(
}
void BluetoothInterface::Observer::SwitchBufferSizeCallback(
- RawAddress* /* remote_addr */, bool /* is_low_latency_buffer_size */) {
+ bool /* is_low_latency_buffer_size */) {
// Do nothing.
}
diff --git a/system/service/hal/bluetooth_interface.h b/system/service/hal/bluetooth_interface.h
index 50c35f656d..da68c9ce09 100644
--- a/system/service/hal/bluetooth_interface.h
+++ b/system/service/hal/bluetooth_interface.h
@@ -16,7 +16,6 @@
#pragma once
-#include <base/macros.h>
#include <hardware/bluetooth.h>
#include "types/raw_address.h"
@@ -83,8 +82,7 @@ class BluetoothInterface {
int retransmission_count, int packets_not_receive_count,
int negative_acknowledgement_count);
- virtual void SwitchBufferSizeCallback(RawAddress* remote_addr,
- bool is_low_latency_buffer_size);
+ virtual void SwitchBufferSizeCallback(bool is_low_latency_buffer_size);
// TODO(armansito): Complete the list of callbacks.
};
@@ -127,10 +125,10 @@ class BluetoothInterface {
protected:
BluetoothInterface() = default;
- virtual ~BluetoothInterface() = default;
+ BluetoothInterface(const BluetoothInterface&) = delete;
+ BluetoothInterface& operator=(const BluetoothInterface&) = delete;
- private:
- DISALLOW_COPY_AND_ASSIGN(BluetoothInterface);
+ virtual ~BluetoothInterface() = default;
};
} // namespace hal
diff --git a/system/service/hal/fake_bluetooth_av_interface.h b/system/service/hal/fake_bluetooth_av_interface.h
index c97c9a3180..e4a45ceeed 100644
--- a/system/service/hal/fake_bluetooth_av_interface.h
+++ b/system/service/hal/fake_bluetooth_av_interface.h
@@ -16,7 +16,6 @@
#pragma once
-#include <base/macros.h>
#include <base/observer_list.h>
#include "abstract_observer_list.h"
@@ -56,6 +55,10 @@ class FakeBluetoothAvInterface : public BluetoothAvInterface {
std::shared_ptr<TestA2dpSourceHandler> a2dp_source_handler);
FakeBluetoothAvInterface(
std::shared_ptr<TestA2dpSinkHandler> a2dp_sink_handler);
+
+ FakeBluetoothAvInterface(const FakeBluetoothAvInterface&) = delete;
+ FakeBluetoothAvInterface& operator=(const FakeBluetoothAvInterface&) = delete;
+
~FakeBluetoothAvInterface();
// The methods below can be used to notify observers with certain events and
@@ -92,8 +95,6 @@ class FakeBluetoothAvInterface : public BluetoothAvInterface {
private:
btbase::AbstractObserverList<A2dpSourceObserver> a2dp_source_observers_;
btbase::AbstractObserverList<A2dpSinkObserver> a2dp_sink_observers_;
-
- DISALLOW_COPY_AND_ASSIGN(FakeBluetoothAvInterface);
};
} // namespace hal
diff --git a/system/service/hal/fake_bluetooth_gatt_interface.h b/system/service/hal/fake_bluetooth_gatt_interface.h
index d6e917fb9b..eb3b9bf342 100644
--- a/system/service/hal/fake_bluetooth_gatt_interface.h
+++ b/system/service/hal/fake_bluetooth_gatt_interface.h
@@ -16,7 +16,6 @@
#pragma once
-#include <base/macros.h>
#include <base/observer_list.h>
#include <vector>
@@ -75,6 +74,11 @@ class FakeBluetoothGattInterface : public BluetoothGattInterface {
std::shared_ptr<BleScannerInterface> scanner_handler,
std::shared_ptr<TestClientHandler> client_handler,
std::shared_ptr<TestServerHandler> server_handler);
+
+ FakeBluetoothGattInterface(const FakeBluetoothGattInterface&) = delete;
+ FakeBluetoothGattInterface& operator=(const FakeBluetoothGattInterface&) =
+ delete;
+
~FakeBluetoothGattInterface();
// The methods below can be used to notify observers with certain events and
@@ -148,8 +152,6 @@ class FakeBluetoothGattInterface : public BluetoothGattInterface {
std::shared_ptr<BleScannerInterface> scanner_handler_;
std::shared_ptr<TestClientHandler> client_handler_;
std::shared_ptr<TestServerHandler> server_handler_;
-
- DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattInterface);
};
} // namespace hal
diff --git a/system/service/hal/fake_bluetooth_interface.cc b/system/service/hal/fake_bluetooth_interface.cc
index 729778d4cd..33209b494a 100644
--- a/system/service/hal/fake_bluetooth_interface.cc
+++ b/system/service/hal/fake_bluetooth_interface.cc
@@ -81,6 +81,7 @@ bt_interface_t fake_bt_iface = {
nullptr, /* set_dynamic_audio_buffer_size */
nullptr, /* generate_local_oob_data */
nullptr, /* allow_low_latency_audio */
+ nullptr, /* clear_event_filter */
};
} // namespace
diff --git a/system/service/hal/fake_bluetooth_interface.h b/system/service/hal/fake_bluetooth_interface.h
index 9ea99b50c4..08f189a737 100644
--- a/system/service/hal/fake_bluetooth_interface.h
+++ b/system/service/hal/fake_bluetooth_interface.h
@@ -14,7 +14,6 @@
// limitations under the License.
//
-#include <base/macros.h>
#include <base/observer_list.h>
#include "abstract_observer_list.h"
@@ -44,6 +43,9 @@ class FakeBluetoothInterface : public BluetoothInterface {
static Manager* GetManager();
FakeBluetoothInterface() = default;
+ FakeBluetoothInterface(const FakeBluetoothInterface&) = delete;
+ FakeBluetoothInterface& operator=(const FakeBluetoothInterface&) = delete;
+
~FakeBluetoothInterface() override = default;
// Notifies the observers that the adapter state changed to |state|.
@@ -70,8 +72,6 @@ class FakeBluetoothInterface : public BluetoothInterface {
private:
btbase::AbstractObserverList<Observer> observers_;
-
- DISALLOW_COPY_AND_ASSIGN(FakeBluetoothInterface);
};
} // namespace hal
diff --git a/system/service/ipc/binder/bluetooth_a2dp_sink_binder_server.h b/system/service/ipc/binder/bluetooth_a2dp_sink_binder_server.h
index e18af54788..f54733cfa0 100644
--- a/system/service/ipc/binder/bluetooth_a2dp_sink_binder_server.h
+++ b/system/service/ipc/binder/bluetooth_a2dp_sink_binder_server.h
@@ -19,8 +19,6 @@
#include <map>
#include <string>
-#include <base/macros.h>
-
#include <android/bluetooth/BnBluetoothA2dpSink.h>
#include <android/bluetooth/IBluetoothA2dpSinkCallback.h>
@@ -40,6 +38,10 @@ class BluetoothA2dpSinkBinderServer
public bluetooth::A2dpSink::Delegate {
public:
explicit BluetoothA2dpSinkBinderServer(bluetooth::Adapter* adapter);
+ BluetoothA2dpSinkBinderServer(const BluetoothA2dpSinkBinderServer&) = delete;
+ BluetoothA2dpSinkBinderServer& operator=(
+ const BluetoothA2dpSinkBinderServer&) = delete;
+
~BluetoothA2dpSinkBinderServer() override = default;
// IBluetoothA2dpSink implementation:
@@ -78,8 +80,6 @@ class BluetoothA2dpSinkBinderServer
bluetooth::BluetoothInstance* instance) override;
bluetooth::Adapter* adapter_; // weak
-
- DISALLOW_COPY_AND_ASSIGN(BluetoothA2dpSinkBinderServer);
};
} // namespace binder
diff --git a/system/service/ipc/binder/bluetooth_a2dp_source_binder_server.h b/system/service/ipc/binder/bluetooth_a2dp_source_binder_server.h
index 160a38adc1..3800a962ec 100644
--- a/system/service/ipc/binder/bluetooth_a2dp_source_binder_server.h
+++ b/system/service/ipc/binder/bluetooth_a2dp_source_binder_server.h
@@ -20,8 +20,6 @@
#include <string>
#include <vector>
-#include <base/macros.h>
-
#include <android/bluetooth/BnBluetoothA2dpSource.h>
#include <android/bluetooth/IBluetoothA2dpSourceCallback.h>
@@ -41,6 +39,11 @@ class BluetoothA2dpSourceBinderServer
public bluetooth::A2dpSource::Delegate {
public:
explicit BluetoothA2dpSourceBinderServer(bluetooth::Adapter* adapter);
+ BluetoothA2dpSourceBinderServer(const BluetoothA2dpSourceBinderServer&) =
+ delete;
+ BluetoothA2dpSourceBinderServer& operator=(
+ const BluetoothA2dpSourceBinderServer&) = delete;
+
~BluetoothA2dpSourceBinderServer() override;
bool HasInstance();
@@ -87,8 +90,6 @@ class BluetoothA2dpSourceBinderServer
bluetooth::BluetoothInstance* instance) override;
bluetooth::Adapter* const adapter_; // weak
-
- DISALLOW_COPY_AND_ASSIGN(BluetoothA2dpSourceBinderServer);
};
} // namespace binder
diff --git a/system/service/ipc/binder/bluetooth_avrcp_control_binder_server.h b/system/service/ipc/binder/bluetooth_avrcp_control_binder_server.h
index 11cf1f3d3e..00b5921b8e 100644
--- a/system/service/ipc/binder/bluetooth_avrcp_control_binder_server.h
+++ b/system/service/ipc/binder/bluetooth_avrcp_control_binder_server.h
@@ -19,8 +19,6 @@
#include <map>
#include <string>
-#include "base/macros.h"
-
#include "android/bluetooth/BnBluetoothAvrcpControl.h"
#include "android/bluetooth/IBluetoothAvrcpControlCallback.h"
@@ -40,6 +38,11 @@ class BluetoothAvrcpControlBinderServer
public bluetooth::AvrcpControl::Delegate {
public:
explicit BluetoothAvrcpControlBinderServer(bluetooth::Adapter* adapter);
+ BluetoothAvrcpControlBinderServer(const BluetoothAvrcpControlBinderServer&) =
+ delete;
+ BluetoothAvrcpControlBinderServer& operator=(
+ const BluetoothAvrcpControlBinderServer&) = delete;
+
~BluetoothAvrcpControlBinderServer() override = default;
// IBluetoothAvrcpControl implementation:
@@ -81,8 +84,6 @@ class BluetoothAvrcpControlBinderServer
std::shared_ptr<bluetooth::AvrcpControl> GetAvrcpControl(int id);
bluetooth::Adapter* adapter_; // weak
-
- DISALLOW_COPY_AND_ASSIGN(BluetoothAvrcpControlBinderServer);
};
} // namespace binder
diff --git a/system/service/ipc/binder/bluetooth_avrcp_target_binder_server.h b/system/service/ipc/binder/bluetooth_avrcp_target_binder_server.h
index 9d2bba03c3..aeab315978 100644
--- a/system/service/ipc/binder/bluetooth_avrcp_target_binder_server.h
+++ b/system/service/ipc/binder/bluetooth_avrcp_target_binder_server.h
@@ -20,8 +20,6 @@
#include <string>
#include <vector>
-#include "base/macros.h"
-
#include "android/bluetooth/BnBluetoothAvrcpTarget.h"
#include "android/bluetooth/IBluetoothAvrcpTargetCallback.h"
@@ -41,6 +39,11 @@ class BluetoothAvrcpTargetBinderServer
public bluetooth::AvrcpTarget::Delegate {
public:
explicit BluetoothAvrcpTargetBinderServer(bluetooth::Adapter* adapter);
+ BluetoothAvrcpTargetBinderServer(const BluetoothAvrcpTargetBinderServer&) =
+ delete;
+ BluetoothAvrcpTargetBinderServer& operator=(
+ const BluetoothAvrcpTargetBinderServer&) = delete;
+
~BluetoothAvrcpTargetBinderServer() override;
bool HasInstance();
@@ -123,8 +126,6 @@ class BluetoothAvrcpTargetBinderServer
std::shared_ptr<bluetooth::AvrcpTarget> GetAvrcpTarget();
bluetooth::Adapter* const adapter_; // weak
-
- DISALLOW_COPY_AND_ASSIGN(BluetoothAvrcpTargetBinderServer);
};
} // namespace binder
diff --git a/system/service/ipc/binder/bluetooth_binder_server.h b/system/service/ipc/binder/bluetooth_binder_server.h
index 7131e8b430..a389d3f6af 100644
--- a/system/service/ipc/binder/bluetooth_binder_server.h
+++ b/system/service/ipc/binder/bluetooth_binder_server.h
@@ -19,7 +19,6 @@
#include <string>
#include <vector>
-#include <base/macros.h>
#include <utils/String16.h>
#include <utils/Vector.h>
@@ -66,6 +65,10 @@ class BluetoothBinderServer : public BnBluetooth,
public bluetooth::Adapter::Observer {
public:
explicit BluetoothBinderServer(bluetooth::Adapter* adapter);
+
+ BluetoothBinderServer(const BluetoothBinderServer&) = delete;
+ BluetoothBinderServer& operator=(const BluetoothBinderServer&) = delete;
+
~BluetoothBinderServer() override;
// IBluetooth overrides:
@@ -188,8 +191,6 @@ class BluetoothBinderServer : public BnBluetooth,
// The IBluetoothAvrcpTarget interface handle. This is lazily initialized on
// the first call to GetAvrcpTargetInterface().
android::sp<BluetoothAvrcpTargetBinderServer> avrcp_target_interface_;
-
- DISALLOW_COPY_AND_ASSIGN(BluetoothBinderServer);
};
} // namespace binder
diff --git a/system/service/ipc/binder/bluetooth_gatt_client_binder_server.h b/system/service/ipc/binder/bluetooth_gatt_client_binder_server.h
index 65b8b60e82..28fa325545 100644
--- a/system/service/ipc/binder/bluetooth_gatt_client_binder_server.h
+++ b/system/service/ipc/binder/bluetooth_gatt_client_binder_server.h
@@ -16,8 +16,6 @@
#pragma once
-#include <base/macros.h>
-
#include <android/bluetooth/BnBluetoothGattClient.h>
#include <android/bluetooth/IBluetoothGattClientCallback.h>
@@ -41,6 +39,12 @@ class BluetoothGattClientBinderServer : public BnBluetoothGattClient,
public InterfaceWithInstancesBase {
public:
explicit BluetoothGattClientBinderServer(bluetooth::Adapter* adapter);
+
+ BluetoothGattClientBinderServer(const BluetoothGattClientBinderServer&) =
+ delete;
+ BluetoothGattClientBinderServer& operator=(
+ const BluetoothGattClientBinderServer&) = delete;
+
~BluetoothGattClientBinderServer() override = default;
// IBluetoothGattClient overrides:
@@ -67,8 +71,6 @@ class BluetoothGattClientBinderServer : public BnBluetoothGattClient,
bluetooth::BluetoothInstance* instance) override;
bluetooth::Adapter* adapter_; // weak
-
- DISALLOW_COPY_AND_ASSIGN(BluetoothGattClientBinderServer);
};
} // namespace binder
diff --git a/system/service/ipc/binder/bluetooth_gatt_server_binder_server.h b/system/service/ipc/binder/bluetooth_gatt_server_binder_server.h
index 925339af17..34fb7c5843 100644
--- a/system/service/ipc/binder/bluetooth_gatt_server_binder_server.h
+++ b/system/service/ipc/binder/bluetooth_gatt_server_binder_server.h
@@ -16,8 +16,6 @@
#pragma once
-#include <base/macros.h>
-
#include <android/bluetooth/BnBluetoothGattServer.h>
#include <android/bluetooth/IBluetoothGattServerCallback.h>
@@ -42,6 +40,12 @@ class BluetoothGattServerBinderServer : public BnBluetoothGattServer,
public bluetooth::GattServer::Delegate {
public:
explicit BluetoothGattServerBinderServer(bluetooth::Adapter* adapter);
+
+ BluetoothGattServerBinderServer(const BluetoothGattServerBinderServer&) =
+ delete;
+ BluetoothGattServerBinderServer& operator=(
+ const BluetoothGattServerBinderServer&) = delete;
+
~BluetoothGattServerBinderServer() override = default;
// IBluetoothGattServer overrides:
@@ -109,8 +113,6 @@ class BluetoothGattServerBinderServer : public BnBluetoothGattServer,
bluetooth::BluetoothInstance* instance) override;
bluetooth::Adapter* adapter_; // weak
-
- DISALLOW_COPY_AND_ASSIGN(BluetoothGattServerBinderServer);
};
} // namespace binder
diff --git a/system/service/ipc/binder/bluetooth_le_advertiser_binder_server.h b/system/service/ipc/binder/bluetooth_le_advertiser_binder_server.h
index 6602f5afb9..a8fca24d42 100644
--- a/system/service/ipc/binder/bluetooth_le_advertiser_binder_server.h
+++ b/system/service/ipc/binder/bluetooth_le_advertiser_binder_server.h
@@ -18,8 +18,6 @@
#include <memory>
-#include <base/macros.h>
-
#include <android/bluetooth/IBluetoothLeAdvertiserCallback.h>
#include "android/bluetooth/BnBluetoothLeAdvertiser.h"
@@ -45,6 +43,12 @@ class BluetoothLeAdvertiserBinderServer : public BnBluetoothLeAdvertiser,
public InterfaceWithInstancesBase {
public:
explicit BluetoothLeAdvertiserBinderServer(bluetooth::Adapter* adapter);
+
+ BluetoothLeAdvertiserBinderServer(const BluetoothLeAdvertiserBinderServer&) =
+ delete;
+ BluetoothLeAdvertiserBinderServer& operator=(
+ const BluetoothLeAdvertiserBinderServer&) = delete;
+
~BluetoothLeAdvertiserBinderServer() override;
// IBluetoothLowEnergy overrides:
@@ -77,8 +81,6 @@ class BluetoothLeAdvertiserBinderServer : public BnBluetoothLeAdvertiser,
bluetooth::BluetoothInstance* instance) override;
bluetooth::Adapter* adapter_; // weak
-
- DISALLOW_COPY_AND_ASSIGN(BluetoothLeAdvertiserBinderServer);
};
} // namespace binder
diff --git a/system/service/ipc/binder/bluetooth_le_scanner_binder_server.h b/system/service/ipc/binder/bluetooth_le_scanner_binder_server.h
index 0cc3ae94a6..3288a4cc93 100644
--- a/system/service/ipc/binder/bluetooth_le_scanner_binder_server.h
+++ b/system/service/ipc/binder/bluetooth_le_scanner_binder_server.h
@@ -18,8 +18,6 @@
#include <memory>
-#include <base/macros.h>
-
#include <android/bluetooth/IBluetoothLeScannerCallback.h>
#include "android/bluetooth/BnBluetoothLeScanner.h"
@@ -47,6 +45,11 @@ class BluetoothLeScannerBinderServer
public bluetooth::LowEnergyScanner::Delegate {
public:
explicit BluetoothLeScannerBinderServer(bluetooth::Adapter* adapter);
+ BluetoothLeScannerBinderServer(const BluetoothLeScannerBinderServer&) =
+ delete;
+ BluetoothLeScannerBinderServer& operator=(
+ const BluetoothLeScannerBinderServer&) = delete;
+
~BluetoothLeScannerBinderServer() override;
// IBluetoothLowEnergy overrides:
@@ -79,8 +82,6 @@ class BluetoothLeScannerBinderServer
bluetooth::BluetoothInstance* instance) override;
bluetooth::Adapter* adapter_; // weak
-
- DISALLOW_COPY_AND_ASSIGN(BluetoothLeScannerBinderServer);
};
} // namespace binder
diff --git a/system/service/ipc/binder/bluetooth_low_energy_binder_server.h b/system/service/ipc/binder/bluetooth_low_energy_binder_server.h
index 4508b3497f..0db2312fb8 100644
--- a/system/service/ipc/binder/bluetooth_low_energy_binder_server.h
+++ b/system/service/ipc/binder/bluetooth_low_energy_binder_server.h
@@ -18,8 +18,6 @@
#include <memory>
-#include <base/macros.h>
-
#include <android/bluetooth/IBluetoothLowEnergyCallback.h>
#include "android/bluetooth/BnBluetoothLowEnergy.h"
@@ -47,6 +45,11 @@ class BluetoothLowEnergyBinderServer
public bluetooth::LowEnergyClient::Delegate {
public:
explicit BluetoothLowEnergyBinderServer(bluetooth::Adapter* adapter);
+ BluetoothLowEnergyBinderServer(const BluetoothLowEnergyBinderServer&) =
+ delete;
+ BluetoothLowEnergyBinderServer& operator=(
+ const BluetoothLowEnergyBinderServer&) = delete;
+
~BluetoothLowEnergyBinderServer() override;
// IBluetoothLowEnergy overrides:
@@ -83,8 +86,6 @@ class BluetoothLowEnergyBinderServer
bluetooth::BluetoothInstance* instance) override;
bluetooth::Adapter* adapter_; // weak
-
- DISALLOW_COPY_AND_ASSIGN(BluetoothLowEnergyBinderServer);
};
} // namespace binder
diff --git a/system/service/ipc/binder/interface_with_instances_base.h b/system/service/ipc/binder/interface_with_instances_base.h
index 05f2817b1f..4501b00456 100644
--- a/system/service/ipc/binder/interface_with_instances_base.h
+++ b/system/service/ipc/binder/interface_with_instances_base.h
@@ -19,8 +19,6 @@
#include <memory>
#include <unordered_map>
-#include <base/macros.h>
-
#include "bluetooth/uuid.h"
#include "service/bluetooth_instance.h"
#include "service/ipc/binder/remote_callback_map.h"
@@ -40,6 +38,10 @@ class InterfaceWithInstancesBase
virtual public android::RefBase {
public:
InterfaceWithInstancesBase() = default;
+ InterfaceWithInstancesBase(const InterfaceWithInstancesBase&) = delete;
+ InterfaceWithInstancesBase& operator=(const InterfaceWithInstancesBase&) =
+ delete;
+
~InterfaceWithInstancesBase() override = default;
protected:
@@ -99,8 +101,6 @@ class InterfaceWithInstancesBase
RemoteCallbackMap<int, IInterface> id_to_cb_;
std::unordered_map<int, std::shared_ptr<bluetooth::BluetoothInstance>>
id_to_instance_;
-
- DISALLOW_COPY_AND_ASSIGN(InterfaceWithInstancesBase);
};
} // namespace binder
diff --git a/system/service/ipc/binder/ipc_handler_binder.h b/system/service/ipc/binder/ipc_handler_binder.h
index 2edd323d87..e59aef4765 100644
--- a/system/service/ipc/binder/ipc_handler_binder.h
+++ b/system/service/ipc/binder/ipc_handler_binder.h
@@ -16,8 +16,6 @@
#pragma once
-#include <base/macros.h>
-
#include "service/ipc/ipc_handler.h"
#include "service/ipc/ipc_manager.h"
@@ -27,6 +25,10 @@ namespace ipc {
class IPCHandlerBinder : public IPCHandler {
public:
IPCHandlerBinder(bluetooth::Adapter* adapter, IPCManager::Delegate* delegate);
+
+ IPCHandlerBinder(const IPCHandlerBinder&) = delete;
+ IPCHandlerBinder& operator=(const IPCHandlerBinder&) = delete;
+
~IPCHandlerBinder() override;
// IPCHandler overrides:
@@ -38,8 +40,6 @@ class IPCHandlerBinder : public IPCHandler {
// Notify the delegate that IPC has started.
void NotifyStarted();
-
- DISALLOW_COPY_AND_ASSIGN(IPCHandlerBinder);
};
} // namespace ipc
diff --git a/system/service/ipc/binder/remote_callback_list.h b/system/service/ipc/binder/remote_callback_list.h
index e25e550593..f78bc60855 100644
--- a/system/service/ipc/binder/remote_callback_list.h
+++ b/system/service/ipc/binder/remote_callback_list.h
@@ -21,7 +21,6 @@
#include <unordered_map>
#include <base/logging.h>
-#include <base/macros.h>
#include <binder/IBinder.h>
#include <binder/IInterface.h>
@@ -53,6 +52,9 @@ template <typename T>
class RemoteCallbackList final {
public:
RemoteCallbackList() = default;
+ RemoteCallbackList(const RemoteCallbackList&) = delete;
+ RemoteCallbackList& operator=(const RemoteCallbackList&) = delete;
+
~RemoteCallbackList();
// Register and unregister a callback interface. Registering will
@@ -91,8 +93,6 @@ class RemoteCallbackList final {
std::mutex map_lock_;
CallbackMap callbacks_;
-
- DISALLOW_COPY_AND_ASSIGN(RemoteCallbackList);
};
// Template Implementation details below
diff --git a/system/service/ipc/binder/remote_callback_map.h b/system/service/ipc/binder/remote_callback_map.h
index 7f31b5390a..96a717b7f0 100644
--- a/system/service/ipc/binder/remote_callback_map.h
+++ b/system/service/ipc/binder/remote_callback_map.h
@@ -20,7 +20,6 @@
#include <unordered_map>
#include <base/logging.h>
-#include <base/macros.h>
#include <binder/IBinder.h>
#include <binder/IInterface.h>
@@ -38,6 +37,9 @@ template <typename K, typename V>
class RemoteCallbackMap final {
public:
RemoteCallbackMap() = default;
+ RemoteCallbackMap(const RemoteCallbackMap&) = delete;
+ RemoteCallbackMap& operator=(const RemoteCallbackMap&) = delete;
+
~RemoteCallbackMap();
// The Delegate interface is used to notify when a registered callback is
@@ -104,8 +106,6 @@ class RemoteCallbackMap final {
std::mutex map_lock_;
CallbackMap map_;
-
- DISALLOW_COPY_AND_ASSIGN(RemoteCallbackMap);
};
// Template Implementation details below
diff --git a/system/service/ipc/dbus/ipc_handler_dbus.h b/system/service/ipc/dbus/ipc_handler_dbus.h
index 2a83369cf8..4c0a7e9fea 100644
--- a/system/service/ipc/dbus/ipc_handler_dbus.h
+++ b/system/service/ipc/dbus/ipc_handler_dbus.h
@@ -29,6 +29,10 @@ namespace ipc {
class IPCHandlerDBus : public IPCHandler {
public:
IPCHandlerDBus(bluetooth::Adapter* adapter, IPCManager::Delegate* delegate);
+
+ IPCHandlerDBus(const IPCHandlerDBus&) = delete;
+ IPCHandlerDBus& operator=(const IPCHandlerDBus&) = delete;
+
~IPCHandlerDBus() override;
void InitDbus();
@@ -41,8 +45,6 @@ class IPCHandlerDBus : public IPCHandler {
base::Thread* dbus_thread_;
IPCHandlerDBus() = default;
-
- DISALLOW_COPY_AND_ASSIGN(IPCHandlerDBus);
};
} // namespace ipc
diff --git a/system/service/ipc/ipc_handler.h b/system/service/ipc/ipc_handler.h
index 9b7994cf37..473d6e0f31 100644
--- a/system/service/ipc/ipc_handler.h
+++ b/system/service/ipc/ipc_handler.h
@@ -16,7 +16,6 @@
#pragma once
-#include <base/macros.h>
#include <base/memory/ref_counted.h>
#include "service/ipc/ipc_manager.h"
@@ -32,6 +31,10 @@ namespace ipc {
class IPCHandler : public base::RefCountedThreadSafe<IPCHandler> {
public:
IPCHandler(bluetooth::Adapter* adapter, IPCManager::Delegate* delegate);
+
+ IPCHandler(const IPCHandler&) = delete;
+ IPCHandler& operator=(const IPCHandler&) = delete;
+
virtual ~IPCHandler();
// Initializes and runs the IPC mechanism. Returns true on success, false
@@ -55,8 +58,6 @@ class IPCHandler : public base::RefCountedThreadSafe<IPCHandler> {
// The delegate that is interested in notifications from us.
IPCManager::Delegate* delegate_;
-
- DISALLOW_COPY_AND_ASSIGN(IPCHandler);
};
} // namespace ipc
diff --git a/system/service/ipc/ipc_handler_linux.h b/system/service/ipc/ipc_handler_linux.h
index 7cd6efabee..765dda2e21 100644
--- a/system/service/ipc/ipc_handler_linux.h
+++ b/system/service/ipc/ipc_handler_linux.h
@@ -19,7 +19,6 @@
#include <atomic>
#include <base/files/file_path.h>
#include <base/files/scoped_file.h>
-#include <base/macros.h>
#include <base/threading/thread.h>
#include "service/ipc/ipc_handler.h"
@@ -35,6 +34,10 @@ namespace ipc {
class IPCHandlerLinux : public IPCHandler {
public:
IPCHandlerLinux(bluetooth::Adapter* adapter, IPCManager::Delegate* delegate);
+
+ IPCHandlerLinux(const IPCHandlerLinux&) = delete;
+ IPCHandlerLinux& operator=(const IPCHandlerLinux&) = delete;
+
~IPCHandlerLinux() override;
// IPCHandler overrides:
@@ -81,8 +84,6 @@ class IPCHandlerLinux : public IPCHandler {
// The origin thread's task runner.
scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner_;
-
- DISALLOW_COPY_AND_ASSIGN(IPCHandlerLinux);
};
} // namespace ipc
diff --git a/system/service/ipc/ipc_manager.h b/system/service/ipc/ipc_manager.h
index ee960ba6f5..bc5a104e3b 100644
--- a/system/service/ipc/ipc_manager.h
+++ b/system/service/ipc/ipc_manager.h
@@ -18,7 +18,6 @@
#include <memory>
-#include <base/macros.h>
#include <base/memory/ref_counted.h>
namespace bluetooth {
@@ -47,6 +46,9 @@ class IPCManager {
class Delegate {
public:
Delegate() = default;
+ Delegate(const Delegate&) = delete;
+ Delegate& operator=(const Delegate&) = delete;
+
virtual ~Delegate() = default;
// Called when an IPC mechanism has successfully started and is ready for
@@ -56,12 +58,12 @@ class IPCManager {
// Called when an IPC mechanism has stopped. This may happen due to an error
// in initialization or due to a regular shut down routine.
virtual void OnIPCHandlerStopped(Type type) = 0;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Delegate);
};
explicit IPCManager(bluetooth::Adapter* adapter);
+ IPCManager(const IPCManager&) = delete;
+ IPCManager& operator=(const IPCManager&) = delete;
+
~IPCManager();
// Initialize the underlying IPC handler based on |type|, if that type has not
@@ -96,8 +98,6 @@ class IPCManager {
// The Bluetooth adapter instance. This is owned by Daemon so we keep a raw
// pointer to it.
bluetooth::Adapter* adapter_;
-
- DISALLOW_COPY_AND_ASSIGN(IPCManager);
};
} // namespace ipc
diff --git a/system/service/logging_helpers.cc b/system/service/logging_helpers.cc
index 8b53033cc6..78a24e600f 100644
--- a/system/service/logging_helpers.cc
+++ b/system/service/logging_helpers.cc
@@ -112,7 +112,7 @@ const char* BtPropertyText(const bt_property_type_t prop) {
CASE_RETURN_TEXT(BT_PROPERTY_SERVICE_RECORD);
CASE_RETURN_TEXT(BT_PROPERTY_ADAPTER_SCAN_MODE);
CASE_RETURN_TEXT(BT_PROPERTY_ADAPTER_BONDED_DEVICES);
- CASE_RETURN_TEXT(BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT);
+ CASE_RETURN_TEXT(BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT);
CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_FRIENDLY_NAME);
CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_RSSI);
CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_VERSION_INFO);
diff --git a/system/service/low_energy_advertiser.h b/system/service/low_energy_advertiser.h
index ec0dd748b0..46d5316965 100644
--- a/system/service/low_energy_advertiser.h
+++ b/system/service/low_energy_advertiser.h
@@ -21,7 +21,6 @@
#include <map>
#include <mutex>
-#include <base/macros.h>
#include <bluetooth/uuid.h>
#include "service/bluetooth_instance.h"
@@ -42,6 +41,9 @@ class Adapter;
// should be obtained through the factory.
class LowEnergyAdvertiser : public BluetoothInstance {
public:
+ LowEnergyAdvertiser(const LowEnergyAdvertiser&) = delete;
+ LowEnergyAdvertiser& operator=(const LowEnergyAdvertiser&) = delete;
+
// The destructor automatically unregisters this client instance from the
// stack.
~LowEnergyAdvertiser() override;
@@ -107,8 +109,6 @@ class LowEnergyAdvertiser : public BluetoothInstance {
std::atomic_bool adv_started_;
std::unique_ptr<StatusCallback> adv_start_callback_;
std::unique_ptr<StatusCallback> adv_stop_callback_;
-
- DISALLOW_COPY_AND_ASSIGN(LowEnergyAdvertiser);
};
// LowEnergyAdvertiserFactory is used to register and obtain a per-application
@@ -121,6 +121,10 @@ class LowEnergyAdvertiserFactory : public BluetoothInstanceFactory {
// Don't construct/destruct directly except in tests. Instead, obtain a handle
// from an Adapter instance.
explicit LowEnergyAdvertiserFactory();
+ LowEnergyAdvertiserFactory(const LowEnergyAdvertiserFactory&) = delete;
+ LowEnergyAdvertiserFactory& operator=(const LowEnergyAdvertiserFactory&) =
+ delete;
+
~LowEnergyAdvertiserFactory() override;
// BluetoothInstanceFactory override:
@@ -138,8 +142,6 @@ class LowEnergyAdvertiserFactory : public BluetoothInstanceFactory {
// Map of pending calls to register.
std::mutex pending_calls_lock_;
std::unordered_set<Uuid> pending_calls_;
-
- DISALLOW_COPY_AND_ASSIGN(LowEnergyAdvertiserFactory);
};
} // namespace bluetooth
diff --git a/system/service/low_energy_client.h b/system/service/low_energy_client.h
index a4b60c61e0..ba39357fe7 100644
--- a/system/service/low_energy_client.h
+++ b/system/service/low_energy_client.h
@@ -16,7 +16,6 @@
#pragma once
-#include <base/macros.h>
#include <bluetooth/uuid.h>
#include <atomic>
@@ -53,6 +52,9 @@ class LowEnergyClient : private hal::BluetoothGattInterface::ClientObserver,
class Delegate {
public:
Delegate() = default;
+ Delegate(const Delegate&) = delete;
+ Delegate& operator=(const Delegate&) = delete;
+
virtual ~Delegate() = default;
// Called asynchronously to notify the delegate of connection state change
@@ -62,11 +64,11 @@ class LowEnergyClient : private hal::BluetoothGattInterface::ClientObserver,
// Called asynchronously to notify the delegate of mtu change
virtual void OnMtuChanged(LowEnergyClient* client, int status,
const char* address, int mtu) = 0;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Delegate);
};
+ LowEnergyClient(const LowEnergyClient&) = delete;
+ LowEnergyClient& operator=(const LowEnergyClient&) = delete;
+
// The destructor automatically unregisters this client instance from the
// stack.
~LowEnergyClient() override;
@@ -134,8 +136,6 @@ class LowEnergyClient : private hal::BluetoothGattInterface::ClientObserver,
// Maps bluetooth address to connection id
// TODO(jpawlowski): change type to bimap
std::map<const RawAddress, int, ConnComparator> connection_ids_;
-
- DISALLOW_COPY_AND_ASSIGN(LowEnergyClient);
};
// LowEnergyClientFactory is used to register and obtain a per-application
@@ -149,6 +149,9 @@ class LowEnergyClientFactory
// Don't construct/destruct directly except in tests. Instead, obtain a handle
// from an Adapter instance.
explicit LowEnergyClientFactory(Adapter& adapter);
+ LowEnergyClientFactory(const LowEnergyClientFactory&) = delete;
+ LowEnergyClientFactory& operator=(const LowEnergyClientFactory&) = delete;
+
~LowEnergyClientFactory() override;
// BluetoothInstanceFactory override:
@@ -169,8 +172,6 @@ class LowEnergyClientFactory
// Raw pointer to the Adapter that owns this factory.
Adapter& adapter_;
-
- DISALLOW_COPY_AND_ASSIGN(LowEnergyClientFactory);
};
} // namespace bluetooth
diff --git a/system/service/low_energy_scanner.h b/system/service/low_energy_scanner.h
index 6325c41cf2..627f287f83 100644
--- a/system/service/low_energy_scanner.h
+++ b/system/service/low_energy_scanner.h
@@ -16,7 +16,6 @@
#pragma once
-#include <base/macros.h>
#include <bluetooth/uuid.h>
#include <atomic>
@@ -49,17 +48,20 @@ class LowEnergyScanner : private hal::BluetoothGattInterface::ScannerObserver,
class Delegate {
public:
Delegate() = default;
+ Delegate(const Delegate&) = delete;
+ Delegate& operator=(const Delegate&) = delete;
+
virtual ~Delegate() = default;
// Called asynchronously to notify the delegate of nearby BLE advertisers
// found during a device scan.
virtual void OnScanResult(LowEnergyScanner* client,
const ScanResult& scan_result) = 0;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Delegate);
};
+ LowEnergyScanner(const LowEnergyScanner&) = delete;
+ LowEnergyScanner& operator=(const LowEnergyScanner&) = delete;
+
// The destructor automatically unregisters this client instance from the
// stack.
~LowEnergyScanner() override;
@@ -120,8 +122,6 @@ class LowEnergyScanner : private hal::BluetoothGattInterface::ScannerObserver,
// instance.
std::mutex delegate_mutex_;
Delegate* delegate_;
-
- DISALLOW_COPY_AND_ASSIGN(LowEnergyScanner);
};
// LowEnergyScannerFactory is used to register and obtain a per-application
@@ -135,6 +135,9 @@ class LowEnergyScannerFactory
// Don't construct/destruct directly except in tests. Instead, obtain a handle
// from an Adapter instance.
explicit LowEnergyScannerFactory(Adapter& adapter);
+ LowEnergyScannerFactory(const LowEnergyScannerFactory&) = delete;
+ LowEnergyScannerFactory& operator=(const LowEnergyScannerFactory&) = delete;
+
~LowEnergyScannerFactory() override;
// BluetoothInstanceFactory override:
@@ -155,8 +158,6 @@ class LowEnergyScannerFactory
// Raw pointer to the Adapter that owns this factory.
Adapter& adapter_;
-
- DISALLOW_COPY_AND_ASSIGN(LowEnergyScannerFactory);
};
} // namespace bluetooth
diff --git a/system/service/settings.h b/system/service/settings.h
index 1f298d6c0e..38e5ca98b2 100644
--- a/system/service/settings.h
+++ b/system/service/settings.h
@@ -19,7 +19,6 @@
#include <string>
#include <base/files/file_path.h>
-#include <base/macros.h>
namespace bluetooth {
@@ -32,6 +31,9 @@ class Settings {
static const char kHelp[];
Settings();
+ Settings(const Settings&) = delete;
+ Settings& operator=(const Settings&) = delete;
+
~Settings();
// TODO(armansito): Write an instance method for storing things into a file.
@@ -67,8 +69,6 @@ class Settings {
bool enable_on_start_;
std::string android_ipc_socket_suffix_;
base::FilePath create_ipc_socket_path_;
-
- DISALLOW_COPY_AND_ASSIGN(Settings);
};
} // namespace bluetooth
diff --git a/system/service/test/a2dp_sink_unittest.cc b/system/service/test/a2dp_sink_unittest.cc
index f51e11292d..69545c29c8 100644
--- a/system/service/test/a2dp_sink_unittest.cc
+++ b/system/service/test/a2dp_sink_unittest.cc
@@ -32,15 +32,15 @@ class MockA2dpSinkHandler
: public hal::FakeBluetoothAvInterface::TestA2dpSinkHandler {
public:
MockA2dpSinkHandler() = default;
+ MockA2dpSinkHandler(const MockA2dpSinkHandler&) = delete;
+ MockA2dpSinkHandler& operator=(const MockA2dpSinkHandler&) = delete;
+
~MockA2dpSinkHandler() override = default;
MOCK_METHOD1(Connect, bt_status_t(RawAddress));
MOCK_METHOD1(Disconnect, bt_status_t(RawAddress));
MOCK_METHOD1(SetAudioFocusState, void(int));
MOCK_METHOD1(SetAudioTrackGain, void(float));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockA2dpSinkHandler);
};
class TestDelegate : public A2dpSink::Delegate {
@@ -89,6 +89,9 @@ class TestDelegate : public A2dpSink::Delegate {
class A2dpSinkTest : public ::testing::Test {
public:
A2dpSinkTest() = default;
+ A2dpSinkTest(const A2dpSinkTest&) = delete;
+ A2dpSinkTest& operator=(const A2dpSinkTest&) = delete;
+
~A2dpSinkTest() override = default;
void SetUp() override {
@@ -107,14 +110,14 @@ class A2dpSinkTest : public ::testing::Test {
hal::FakeBluetoothAvInterface* fake_hal_av_iface_;
std::shared_ptr<MockA2dpSinkHandler> mock_handler_;
std::unique_ptr<A2dpSinkFactory> factory_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(A2dpSinkTest);
};
class A2dpSinkPostRegisterTest : public A2dpSinkTest {
public:
A2dpSinkPostRegisterTest() = default;
+ A2dpSinkPostRegisterTest(const A2dpSinkPostRegisterTest&) = delete;
+ A2dpSinkPostRegisterTest& operator=(const A2dpSinkPostRegisterTest&) = delete;
+
~A2dpSinkPostRegisterTest() override = default;
void SetUp() override {
@@ -160,9 +163,6 @@ class A2dpSinkPostRegisterTest : public A2dpSinkTest {
}
std::unique_ptr<A2dpSink> a2dp_sink_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(A2dpSinkPostRegisterTest);
};
TEST_F(A2dpSinkTest, RegisterA2dpSink) {
diff --git a/system/service/test/a2dp_source_unittest.cc b/system/service/test/a2dp_source_unittest.cc
index 5aede818fb..b29172754c 100644
--- a/system/service/test/a2dp_source_unittest.cc
+++ b/system/service/test/a2dp_source_unittest.cc
@@ -32,13 +32,13 @@ class MockA2dpSourceHandler
: public hal::FakeBluetoothAvInterface::TestA2dpSourceHandler {
public:
MockA2dpSourceHandler() = default;
+ MockA2dpSourceHandler(const MockA2dpSourceHandler&) = delete;
+ MockA2dpSourceHandler& operator=(const MockA2dpSourceHandler&) = delete;
+
~MockA2dpSourceHandler() override = default;
MOCK_METHOD1(Connect, bt_status_t(RawAddress));
MOCK_METHOD1(Disconnect, bt_status_t(RawAddress));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockA2dpSourceHandler);
};
class TestDelegate : public A2dpSource::Delegate {
@@ -86,6 +86,9 @@ class TestDelegate : public A2dpSource::Delegate {
class A2dpSourceTest : public ::testing::Test {
public:
A2dpSourceTest() = default;
+ A2dpSourceTest(const A2dpSourceTest&) = delete;
+ A2dpSourceTest& operator=(const A2dpSourceTest&) = delete;
+
~A2dpSourceTest() override = default;
void SetUp() override {
@@ -104,14 +107,15 @@ class A2dpSourceTest : public ::testing::Test {
hal::FakeBluetoothAvInterface* fake_hal_av_iface_;
std::shared_ptr<MockA2dpSourceHandler> mock_handler_;
std::unique_ptr<A2dpSourceFactory> factory_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(A2dpSourceTest);
};
class A2dpSourcePostRegisterTest : public A2dpSourceTest {
public:
A2dpSourcePostRegisterTest() = default;
+ A2dpSourcePostRegisterTest(const A2dpSourcePostRegisterTest&) = delete;
+ A2dpSourcePostRegisterTest& operator=(const A2dpSourcePostRegisterTest&) =
+ delete;
+
~A2dpSourcePostRegisterTest() override = default;
void SetUp() override {
@@ -157,9 +161,6 @@ class A2dpSourcePostRegisterTest : public A2dpSourceTest {
}
std::unique_ptr<A2dpSource> a2dp_source_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(A2dpSourcePostRegisterTest);
};
TEST_F(A2dpSourceTest, RegisterA2dpSource) {
diff --git a/system/service/test/adapter_unittest.cc b/system/service/test/adapter_unittest.cc
index 37b0abbeb5..6c736097dc 100644
--- a/system/service/test/adapter_unittest.cc
+++ b/system/service/test/adapter_unittest.cc
@@ -16,7 +16,6 @@
#include "service/adapter.h"
-#include <base/macros.h>
#include <gtest/gtest.h>
#include "service/hal/fake_bluetooth_gatt_interface.h"
@@ -30,6 +29,9 @@ namespace {
class AdapterTest : public ::testing::Test {
public:
AdapterTest() = default;
+ AdapterTest(const AdapterTest&) = delete;
+ AdapterTest& operator=(const AdapterTest&) = delete;
+
~AdapterTest() override = default;
void SetUp() override {
@@ -55,9 +57,6 @@ class AdapterTest : public ::testing::Test {
hal::FakeBluetoothInterface* fake_hal_iface_;
hal::FakeBluetoothInterface::Manager* fake_hal_manager_;
std::unique_ptr<Adapter> adapter_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(AdapterTest);
};
class TestObserver final : public bluetooth::Adapter::Observer {
@@ -71,6 +70,9 @@ class TestObserver final : public bluetooth::Adapter::Observer {
adapter_->AddObserver(this);
}
+ TestObserver(const TestObserver&) = delete;
+ TestObserver& operator=(const TestObserver&) = delete;
+
~TestObserver() override { adapter_->RemoveObserver(this); }
bluetooth::AdapterState prev_state() const { return prev_state_; }
@@ -106,8 +108,6 @@ class TestObserver final : public bluetooth::Adapter::Observer {
bluetooth::AdapterState prev_state_, cur_state_;
std::string last_connection_state_address_;
bool last_device_connected_state_;
-
- DISALLOW_COPY_AND_ASSIGN(TestObserver);
};
TEST_F(AdapterTest, IsEnabled) {
diff --git a/system/service/test/gatt_client_unittest.cc b/system/service/test/gatt_client_unittest.cc
index 71850cdea9..c7c02091a8 100644
--- a/system/service/test/gatt_client_unittest.cc
+++ b/system/service/test/gatt_client_unittest.cc
@@ -16,7 +16,6 @@
#include "service/gatt_client.h"
-#include <base/macros.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
@@ -33,6 +32,9 @@ class MockGattHandler
: public hal::FakeBluetoothGattInterface::TestClientHandler {
public:
MockGattHandler() = default;
+ MockGattHandler(const MockGattHandler&) = delete;
+ MockGattHandler& operator=(const MockGattHandler&) = delete;
+
~MockGattHandler() override = default;
MOCK_METHOD2(RegisterClient,
@@ -41,14 +43,14 @@ class MockGattHandler
MOCK_METHOD1(Scan, bt_status_t(bool));
MOCK_METHOD4(Connect, bt_status_t(int, const RawAddress&, bool, int));
MOCK_METHOD3(Disconnect, bt_status_t(int, const RawAddress&, int));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockGattHandler);
};
class GattClientTest : public ::testing::Test {
public:
GattClientTest() = default;
+ GattClientTest(const GattClientTest&) = delete;
+ GattClientTest& operator=(const GattClientTest&) = delete;
+
~GattClientTest() override = default;
void SetUp() override {
@@ -74,9 +76,6 @@ class GattClientTest : public ::testing::Test {
hal::FakeBluetoothGattInterface* fake_hal_gatt_iface_;
std::shared_ptr<MockGattHandler> mock_handler_;
std::unique_ptr<GattClientFactory> factory_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(GattClientTest);
};
TEST_F(GattClientTest, RegisterInstance) {
diff --git a/system/service/test/gatt_server_unittest.cc b/system/service/test/gatt_server_unittest.cc
index 467100c170..f0e6f98d33 100644
--- a/system/service/test/gatt_server_unittest.cc
+++ b/system/service/test/gatt_server_unittest.cc
@@ -32,6 +32,9 @@ class MockGattHandler
: public hal::FakeBluetoothGattInterface::TestServerHandler {
public:
MockGattHandler() = default;
+ MockGattHandler(const MockGattHandler&) = delete;
+ MockGattHandler& operator=(const MockGattHandler&) = delete;
+
~MockGattHandler() override = default;
MOCK_METHOD2(RegisterServer,
@@ -47,9 +50,6 @@ class MockGattHandler
bt_status_t(int, int, int, int, std::vector<uint8_t>));
MOCK_METHOD4(SendResponse,
bt_status_t(int, int, int, const btgatt_response_t&));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockGattHandler);
};
class TestDelegate : public GattServer::Delegate {
@@ -179,6 +179,9 @@ class TestDelegate : public GattServer::Delegate {
class GattServerTest : public ::testing::Test {
public:
GattServerTest() = default;
+ GattServerTest(const GattServerTest&) = delete;
+ GattServerTest& operator=(const GattServerTest&) = delete;
+
~GattServerTest() override = default;
void SetUp() override {
@@ -201,9 +204,6 @@ class GattServerTest : public ::testing::Test {
hal::FakeBluetoothGattInterface* fake_hal_gatt_iface_;
std::shared_ptr<MockGattHandler> mock_handler_;
std::unique_ptr<GattServerFactory> factory_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(GattServerTest);
};
const int kDefaultServerId = 4;
@@ -211,6 +211,10 @@ const int kDefaultServerId = 4;
class GattServerPostRegisterTest : public GattServerTest {
public:
GattServerPostRegisterTest() = default;
+ GattServerPostRegisterTest(const GattServerPostRegisterTest&) = delete;
+ GattServerPostRegisterTest& operator=(const GattServerPostRegisterTest&) =
+ delete;
+
~GattServerPostRegisterTest() override = default;
void SetUp() override {
@@ -295,9 +299,6 @@ class GattServerPostRegisterTest : public GattServerTest {
uint16_t srvc_handle_;
uint16_t char_handle_;
uint16_t desc_handle_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(GattServerPostRegisterTest);
};
TEST_F(GattServerTest, RegisterServer) {
diff --git a/system/service/test/ipc_linux_unittest.cc b/system/service/test/ipc_linux_unittest.cc
index 176cd6a320..0c3ab31b7d 100644
--- a/system/service/test/ipc_linux_unittest.cc
+++ b/system/service/test/ipc_linux_unittest.cc
@@ -22,7 +22,6 @@
#include <base/at_exit.h>
#include <base/command_line.h>
#include <base/files/scoped_file.h>
-#include <base/macros.h>
#include <base/run_loop.h>
#include <base/strings/stringprintf.h>
#include <gtest/gtest.h>
@@ -45,6 +44,9 @@ const char kTestSocketPath[] = "test_socket_path";
class IPCLinuxTest : public ::testing::Test {
public:
IPCLinuxTest() = default;
+ IPCLinuxTest(const IPCLinuxTest&) = delete;
+ IPCLinuxTest& operator=(const IPCLinuxTest&) = delete;
+
~IPCLinuxTest() override = default;
void SetUp() override {
@@ -109,13 +111,14 @@ class IPCLinuxTest : public ::testing::Test {
std::unique_ptr<bluetooth::Adapter> adapter_;
std::unique_ptr<ipc::IPCManager> ipc_manager_;
base::ScopedFD client_fd_;
-
- DISALLOW_COPY_AND_ASSIGN(IPCLinuxTest);
};
class IPCLinuxTestDisabled : public IPCLinuxTest {
public:
IPCLinuxTestDisabled() = default;
+ IPCLinuxTestDisabled(const IPCLinuxTestDisabled&) = delete;
+ IPCLinuxTestDisabled& operator=(const IPCLinuxTestDisabled&) = delete;
+
~IPCLinuxTestDisabled() override = default;
void SetUpCommandLine() override {
@@ -123,9 +126,6 @@ class IPCLinuxTestDisabled : public IPCLinuxTest {
const base::CommandLine::CharType* argv[] = {"program"};
base::CommandLine::Init(ARRAY_SIZE(argv), argv);
}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(IPCLinuxTestDisabled);
};
class TestDelegate : public ipc::IPCManager::Delegate,
@@ -133,6 +133,9 @@ class TestDelegate : public ipc::IPCManager::Delegate,
public:
TestDelegate() : started_count_(0), stopped_count_(0) {}
+ TestDelegate(const TestDelegate&) = delete;
+ TestDelegate& operator=(const TestDelegate&) = delete;
+
void OnIPCHandlerStarted(ipc::IPCManager::Type type) override {
ASSERT_EQ(ipc::IPCManager::TYPE_LINUX, type);
started_count_++;
@@ -151,8 +154,6 @@ class TestDelegate : public ipc::IPCManager::Delegate,
private:
int started_count_;
int stopped_count_;
-
- DISALLOW_COPY_AND_ASSIGN(TestDelegate);
};
TEST_F(IPCLinuxTestDisabled, StartWithNoSocketPath) {
diff --git a/system/service/test/low_energy_advertiser_unittest.cc b/system/service/test/low_energy_advertiser_unittest.cc
index 3d6a7c23db..f46b80b2af 100644
--- a/system/service/test/low_energy_advertiser_unittest.cc
+++ b/system/service/test/low_energy_advertiser_unittest.cc
@@ -14,7 +14,6 @@
// limitations under the License.
//
-#include <base/macros.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
@@ -43,6 +42,9 @@ namespace {
class MockAdvertiserHandler : public BleAdvertiserInterface {
public:
MockAdvertiserHandler() {}
+ MockAdvertiserHandler(const MockAdvertiserHandler&) = delete;
+ MockAdvertiserHandler& operator=(const MockAdvertiserHandler&) = delete;
+
~MockAdvertiserHandler() override = default;
MOCK_METHOD1(RegisterAdvertiser, void(IdStatusCallback));
@@ -78,14 +80,14 @@ class MockAdvertiserHandler : public BleAdvertiserInterface {
int big_handle,
int reason,
TerminateBIGCallback cb));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockAdvertiserHandler);
};
class LowEnergyAdvertiserTest : public ::testing::Test {
public:
LowEnergyAdvertiserTest() = default;
+ LowEnergyAdvertiserTest(const LowEnergyAdvertiserTest&) = delete;
+ LowEnergyAdvertiserTest& operator=(const LowEnergyAdvertiserTest&) = delete;
+
~LowEnergyAdvertiserTest() override = default;
void SetUp() override {
@@ -106,15 +108,17 @@ class LowEnergyAdvertiserTest : public ::testing::Test {
protected:
std::shared_ptr<MockAdvertiserHandler> mock_handler_;
std::unique_ptr<LowEnergyAdvertiserFactory> ble_advertiser_factory_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(LowEnergyAdvertiserTest);
};
// Used for tests that operate on a pre-registered advertiser.
class LowEnergyAdvertiserPostRegisterTest : public LowEnergyAdvertiserTest {
public:
LowEnergyAdvertiserPostRegisterTest() : next_client_id_(0) {}
+ LowEnergyAdvertiserPostRegisterTest(
+ const LowEnergyAdvertiserPostRegisterTest&) = delete;
+ LowEnergyAdvertiserPostRegisterTest& operator=(
+ const LowEnergyAdvertiserPostRegisterTest&) = delete;
+
~LowEnergyAdvertiserPostRegisterTest() override = default;
void SetUp() override {
@@ -208,8 +212,6 @@ class LowEnergyAdvertiserPostRegisterTest : public LowEnergyAdvertiserTest {
private:
int next_client_id_;
-
- DISALLOW_COPY_AND_ASSIGN(LowEnergyAdvertiserPostRegisterTest);
};
TEST_F(LowEnergyAdvertiserTest, RegisterInstance) {
diff --git a/system/service/test/low_energy_client_unittest.cc b/system/service/test/low_energy_client_unittest.cc
index 389d758237..f2669ba085 100644
--- a/system/service/test/low_energy_client_unittest.cc
+++ b/system/service/test/low_energy_client_unittest.cc
@@ -16,7 +16,6 @@
#include "service/low_energy_client.h"
-#include <base/macros.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
@@ -40,6 +39,9 @@ class MockGattHandler
: public hal::FakeBluetoothGattInterface::TestClientHandler {
public:
MockGattHandler(){};
+ MockGattHandler(const MockGattHandler&) = delete;
+ MockGattHandler& operator=(const MockGattHandler&) = delete;
+
~MockGattHandler() override = default;
MOCK_METHOD2(RegisterClient,
@@ -47,15 +49,15 @@ class MockGattHandler
MOCK_METHOD1(UnregisterClient, bt_status_t(int));
MOCK_METHOD4(Connect, bt_status_t(int, const RawAddress&, bool, int));
MOCK_METHOD3(Disconnect, bt_status_t(int, const RawAddress&, int));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockGattHandler);
};
class TestDelegate : public LowEnergyClient::Delegate {
public:
TestDelegate() : connection_state_count_(0), last_mtu_(0) {}
+ TestDelegate(const TestDelegate&) = delete;
+ TestDelegate& operator=(const TestDelegate&) = delete;
+
~TestDelegate() override = default;
int connection_state_count() const { return connection_state_count_; }
@@ -76,13 +78,14 @@ class TestDelegate : public LowEnergyClient::Delegate {
int connection_state_count_;
int last_mtu_;
-
- DISALLOW_COPY_AND_ASSIGN(TestDelegate);
};
class LowEnergyClientTest : public ::testing::Test {
public:
LowEnergyClientTest() = default;
+ LowEnergyClientTest(const LowEnergyClientTest&) = delete;
+ LowEnergyClientTest& operator=(const LowEnergyClientTest&) = delete;
+
~LowEnergyClientTest() override = default;
void SetUp() override {
@@ -107,15 +110,18 @@ class LowEnergyClientTest : public ::testing::Test {
testing::MockAdapter mock_adapter_;
std::shared_ptr<MockGattHandler> mock_handler_;
std::unique_ptr<LowEnergyClientFactory> ble_factory_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(LowEnergyClientTest);
};
// Used for tests that operate on a pre-registered client.
class LowEnergyClientPostRegisterTest : public LowEnergyClientTest {
public:
LowEnergyClientPostRegisterTest() : next_client_id_(0) {}
+
+ LowEnergyClientPostRegisterTest(const LowEnergyClientPostRegisterTest&) =
+ delete;
+ LowEnergyClientPostRegisterTest& operator=(
+ const LowEnergyClientPostRegisterTest&) = delete;
+
~LowEnergyClientPostRegisterTest() override = default;
void SetUp() override {
@@ -164,8 +170,6 @@ class LowEnergyClientPostRegisterTest : public LowEnergyClientTest {
private:
int next_client_id_;
-
- DISALLOW_COPY_AND_ASSIGN(LowEnergyClientPostRegisterTest);
};
TEST_F(LowEnergyClientTest, RegisterInstance) {
diff --git a/system/service/test/low_energy_scanner_unittest.cc b/system/service/test/low_energy_scanner_unittest.cc
index 5cc5694fba..6abd74322f 100644
--- a/system/service/test/low_energy_scanner_unittest.cc
+++ b/system/service/test/low_energy_scanner_unittest.cc
@@ -16,7 +16,6 @@
#include "service/low_energy_scanner.h"
-#include <base/macros.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
@@ -103,6 +102,9 @@ class TestDelegate : public LowEnergyScanner::Delegate {
public:
TestDelegate() : scan_result_count_(0) {}
+ TestDelegate(const TestDelegate&) = delete;
+ TestDelegate& operator=(const TestDelegate&) = delete;
+
~TestDelegate() override = default;
int scan_result_count() const { return scan_result_count_; }
@@ -118,13 +120,14 @@ class TestDelegate : public LowEnergyScanner::Delegate {
private:
int scan_result_count_;
ScanResult last_scan_result_;
-
- DISALLOW_COPY_AND_ASSIGN(TestDelegate);
};
class LowEnergyScannerTest : public ::testing::Test {
public:
LowEnergyScannerTest() = default;
+ LowEnergyScannerTest(const LowEnergyScannerTest&) = delete;
+ LowEnergyScannerTest& operator=(const LowEnergyScannerTest&) = delete;
+
~LowEnergyScannerTest() override = default;
void SetUp() override {
@@ -147,15 +150,18 @@ class LowEnergyScannerTest : public ::testing::Test {
testing::MockAdapter mock_adapter_;
std::shared_ptr<MockScannerHandler> mock_handler_;
std::unique_ptr<LowEnergyScannerFactory> ble_factory_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(LowEnergyScannerTest);
};
// Used for tests that operate on a pre-registered scanner.
class LowEnergyScannerPostRegisterTest : public LowEnergyScannerTest {
public:
LowEnergyScannerPostRegisterTest() : next_scanner_id_(0) {}
+
+ LowEnergyScannerPostRegisterTest(const LowEnergyScannerPostRegisterTest&) =
+ delete;
+ LowEnergyScannerPostRegisterTest& operator=(
+ const LowEnergyScannerPostRegisterTest&) = delete;
+
~LowEnergyScannerPostRegisterTest() override = default;
void SetUp() override {
@@ -203,8 +209,6 @@ class LowEnergyScannerPostRegisterTest : public LowEnergyScannerTest {
private:
int next_scanner_id_;
-
- DISALLOW_COPY_AND_ASSIGN(LowEnergyScannerPostRegisterTest);
};
TEST_F(LowEnergyScannerTest, RegisterInstance) {
diff --git a/system/service/test/mock_adapter.h b/system/service/test/mock_adapter.h
index b652026858..4042f6a975 100644
--- a/system/service/test/mock_adapter.h
+++ b/system/service/test/mock_adapter.h
@@ -26,6 +26,9 @@ namespace testing {
class MockAdapter : public Adapter {
public:
MockAdapter() = default;
+ MockAdapter(const MockAdapter&) = delete;
+ MockAdapter& operator=(const MockAdapter&) = delete;
+
~MockAdapter() override = default;
MOCK_METHOD1(AddObserver, void(Observer*));
@@ -60,9 +63,6 @@ class MockAdapter : public Adapter {
MOCK_CONST_METHOD0(GetLeScannerFactory, LowEnergyScannerFactory*());
MOCK_CONST_METHOD0(GetGattClientFactory, GattClientFactory*());
MOCK_CONST_METHOD0(GetGattServerFactory, GattServerFactory*());
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockAdapter);
};
} // namespace testing
diff --git a/system/service/test/mock_daemon.h b/system/service/test/mock_daemon.h
index 1c026221d2..410b962b52 100644
--- a/system/service/test/mock_daemon.h
+++ b/system/service/test/mock_daemon.h
@@ -27,15 +27,15 @@ namespace testing {
class MockDaemon : public Daemon {
public:
MockDaemon() = default;
+ MockDaemon(const MockDaemon&) = delete;
+ MockDaemon& operator=(const MockDaemon&) = delete;
+
~MockDaemon() override = default;
MOCK_CONST_METHOD0(GetSettings, Settings*());
MOCK_CONST_METHOD0(GetMessageLoop, btbase::AbstractMessageLoop*());
MOCK_METHOD0(StartMainLoop, void());
MOCK_METHOD0(Init, bool());
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockDaemon);
};
} // namespace testing
diff --git a/system/service/test/settings_unittest.cc b/system/service/test/settings_unittest.cc
index 60d372e375..31baaaaad8 100644
--- a/system/service/test/settings_unittest.cc
+++ b/system/service/test/settings_unittest.cc
@@ -16,7 +16,6 @@
#include <base/at_exit.h>
#include <base/command_line.h>
-#include <base/macros.h>
#include <gtest/gtest.h>
#include "array_utils.h"
@@ -31,6 +30,8 @@ namespace {
class SettingsTest : public ::testing::Test {
public:
SettingsTest() = default;
+ SettingsTest(const SettingsTest&) = delete;
+ SettingsTest& operator=(const SettingsTest&) = delete;
void SetUp() override { base::CommandLine::Reset(); }
@@ -39,9 +40,6 @@ class SettingsTest : public ::testing::Test {
protected:
base::AtExitManager exit_manager_;
Settings settings_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(SettingsTest);
};
TEST_F(SettingsTest, EmptyCommandLine) {
diff --git a/system/stack/Android.bp b/system/stack/Android.bp
index d4e322a6df..8678e6204f 100644
--- a/system/stack/Android.bp
+++ b/system/stack/Android.bp
@@ -240,7 +240,6 @@ cc_test {
"android.hardware.bluetooth.a2dp@1.0",
"android.hardware.bluetooth.audio@2.0",
"android.hardware.bluetooth.audio@2.1",
- "android.hardware.bluetooth.audio@2.2",
"android.hardware.bluetooth.audio-V1-ndk",
"android.system.suspend.control-V1-ndk",
"libaaudio",
@@ -272,7 +271,6 @@ cc_test {
"libbt-hci",
"libbtdevice",
"libg722codec",
- "liblc3codec",
"liblc3",
"libosi",
"libudrv-uipc",
diff --git a/system/stack/acl/btm_ble_connection_establishment.cc b/system/stack/acl/btm_ble_connection_establishment.cc
index 2fef1a5e38..d452a7cbb5 100644
--- a/system/stack/acl/btm_ble_connection_establishment.cc
+++ b/system/stack/acl/btm_ble_connection_establishment.cc
@@ -43,50 +43,6 @@ extern void btm_ble_advertiser_notify_terminated_legacy(
extern bool btm_ble_init_pseudo_addr(tBTM_SEC_DEV_REC* p_dev_rec,
const RawAddress& new_pseudo_addr);
-void btm_send_hci_create_connection(
- uint16_t scan_int, uint16_t scan_win, uint8_t init_filter_policy,
- tBLE_ADDR_TYPE addr_type_peer, const RawAddress& bda_peer,
- tBLE_ADDR_TYPE addr_type_own, uint16_t conn_int_min, uint16_t conn_int_max,
- uint16_t conn_latency, uint16_t conn_timeout, uint16_t min_ce_len,
- uint16_t max_ce_len, uint8_t initiating_phys) {
- ASSERT_LOG(false,
- "When gd_acl enabled this code path should not be exercised");
-
- if (controller_get_interface()->supports_ble_extended_advertising()) {
- EXT_CONN_PHY_CFG phy_cfg[3]; // maximum three phys
-
- int phy_cnt =
- std::bitset<std::numeric_limits<uint8_t>::digits>(initiating_phys)
- .count();
-
- LOG_ASSERT(phy_cnt <= 3) << "More than three phys provided";
- // TODO(jpawlowski): tune parameters for different transports
- for (int i = 0; i < phy_cnt; i++) {
- phy_cfg[i].scan_int = scan_int;
- phy_cfg[i].scan_win = scan_win;
- phy_cfg[i].conn_int_min = conn_int_min;
- phy_cfg[i].conn_int_max = conn_int_max;
- phy_cfg[i].conn_latency = conn_latency;
- phy_cfg[i].sup_timeout = conn_timeout;
- phy_cfg[i].min_ce_len = min_ce_len;
- phy_cfg[i].max_ce_len = max_ce_len;
- }
-
- addr_type_peer &= ~BLE_ADDR_TYPE_ID_BIT;
- btsnd_hcic_ble_ext_create_conn(init_filter_policy, addr_type_own,
- addr_type_peer, bda_peer, initiating_phys,
- phy_cfg);
- } else {
- btsnd_hcic_ble_create_ll_conn(scan_int, scan_win, init_filter_policy,
- addr_type_peer, bda_peer, addr_type_own,
- conn_int_min, conn_int_max, conn_latency,
- conn_timeout, min_ce_len, max_ce_len);
- }
-
- btm_cb.ble_ctr_cb.set_connection_state_connecting();
- btm_ble_set_topology_mask(BTM_BLE_STATE_INIT_BIT);
-}
-
/** LE connection complete. */
void btm_ble_create_ll_conn_complete(tHCI_STATUS status) {
if (status == HCI_SUCCESS) return;
diff --git a/system/stack/avrc/avrc_pars_ct.cc b/system/stack/avrc/avrc_pars_ct.cc
index 298f6eedf2..78962c773b 100644
--- a/system/stack/avrc/avrc_pars_ct.cc
+++ b/system/stack/avrc/avrc_pars_ct.cc
@@ -581,6 +581,10 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp(tAVRC_MSG_VENDOR* p_msg,
p_result->get_caps.capability_id,
p_result->get_caps.count);
if (p_result->get_caps.capability_id == AVRC_CAP_COMPANY_ID) {
+ if (p_result->get_caps.count > AVRC_CAP_MAX_NUM_COMP_ID) {
+ android_errorWriteLog(0x534e4554, "205837191");
+ return AVRC_STS_INTERNAL_ERR;
+ }
min_len += MIN(p_result->get_caps.count, AVRC_CAP_MAX_NUM_COMP_ID) * 3;
if (len < min_len) goto length_error;
for (int xx = 0; ((xx < p_result->get_caps.count) &&
@@ -590,6 +594,10 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp(tAVRC_MSG_VENDOR* p_msg,
}
} else if (p_result->get_caps.capability_id ==
AVRC_CAP_EVENTS_SUPPORTED) {
+ if (p_result->get_caps.count > AVRC_CAP_MAX_NUM_COMP_ID) {
+ android_errorWriteLog(0x534e4554, "205837191");
+ return AVRC_STS_INTERNAL_ERR;
+ }
min_len += MIN(p_result->get_caps.count, AVRC_CAP_MAX_NUM_EVT_ID);
if (len < min_len) goto length_error;
for (int xx = 0; ((xx < p_result->get_caps.count) &&
diff --git a/system/stack/btm/btm_ble.cc b/system/stack/btm/btm_ble.cc
index 94f862dc98..10977455b4 100644
--- a/system/stack/btm/btm_ble.cc
+++ b/system/stack/btm/btm_ble.cc
@@ -2073,32 +2073,6 @@ void btm_ble_reset_id(void) {
}));
}
-/* This function set a random address to local controller. It also temporarily
- * disable scans and adv before sending the command to the controller. */
-void btm_ble_set_random_address(const RawAddress& random_bda) {
- tBTM_LE_RANDOM_CB* p_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
- tBTM_BLE_CB* p_ble_cb = &btm_cb.ble_ctr_cb;
- const bool adv_mode = btm_cb.ble_ctr_cb.inq_var.adv_mode;
-
- if (adv_mode == BTM_BLE_ADV_ENABLE)
- btsnd_hcic_ble_set_adv_enable(BTM_BLE_ADV_DISABLE);
- if (p_ble_cb->is_ble_scan_active()) {
- btm_ble_stop_scan();
- }
- btm_ble_suspend_bg_conn();
-
- p_cb->private_addr = random_bda;
- btsnd_hcic_ble_set_random_addr(p_cb->private_addr);
- LOG_DEBUG("Updating local random address:%s", PRIVATE_ADDRESS(random_bda));
-
- if (adv_mode == BTM_BLE_ADV_ENABLE)
- btsnd_hcic_ble_set_adv_enable(BTM_BLE_ADV_ENABLE);
- if (p_ble_cb->is_ble_scan_active()) {
- btm_ble_start_scan();
- }
- btm_ble_resume_bg_conn();
-}
-
/*******************************************************************************
*
* Function btm_ble_get_acl_remote_addr
diff --git a/system/stack/btm/btm_ble_addr.cc b/system/stack/btm/btm_ble_addr.cc
index 44436b9f3e..34424dbf1f 100644
--- a/system/stack/btm/btm_ble_addr.cc
+++ b/system/stack/btm/btm_ble_addr.cc
@@ -38,8 +38,6 @@
extern tBTM_CB btm_cb;
-void btm_ble_set_random_address(const RawAddress& random_bda);
-
/* This function generates Resolvable Private Address (RPA) from Identity
* Resolving Key |irk| and |random|*/
static RawAddress generate_rpa_from_irk_and_rand(const Octet16& irk,
@@ -195,6 +193,8 @@ tBTM_SEC_DEV_REC* btm_ble_resolve_random_addr(const RawAddress& random_bda) {
/** Find the security record whose LE identity address is matching */
static tBTM_SEC_DEV_REC* btm_find_dev_by_identity_addr(
const RawAddress& bd_addr, uint8_t addr_type) {
+ if (btm_cb.sec_dev_rec == nullptr) return nullptr;
+
list_node_t* end = list_end(btm_cb.sec_dev_rec);
for (list_node_t* node = list_begin(btm_cb.sec_dev_rec); node != end;
node = list_next(node)) {
diff --git a/system/stack/btm/btm_ble_bgconn.cc b/system/stack/btm/btm_ble_bgconn.cc
index 65c1b18673..f725351191 100644
--- a/system/stack/btm/btm_ble_bgconn.cc
+++ b/system/stack/btm/btm_ble_bgconn.cc
@@ -39,12 +39,6 @@
extern tBTM_CB btm_cb;
-extern void btm_send_hci_create_connection(
- uint16_t scan_int, uint16_t scan_win, uint8_t init_filter_policy,
- uint8_t addr_type_peer, const RawAddress& bda_peer, uint8_t addr_type_own,
- uint16_t conn_int_min, uint16_t conn_int_max, uint16_t conn_latency,
- uint16_t conn_timeout, uint16_t min_ce_len, uint16_t max_ce_len,
- uint8_t phy);
extern void btm_ble_create_conn_cancel();
namespace {
diff --git a/system/stack/btm/btm_ble_int.h b/system/stack/btm/btm_ble_int.h
index 00c6aec5ab..dfb9f2277b 100644
--- a/system/stack/btm/btm_ble_int.h
+++ b/system/stack/btm/btm_ble_int.h
@@ -137,7 +137,6 @@ extern void btm_ble_adv_filter_init(void);
extern bool btm_ble_topology_check(tBTM_BLE_STATE_MASK request);
extern bool btm_ble_clear_topology_mask(tBTM_BLE_STATE_MASK request_state);
extern bool btm_ble_set_topology_mask(tBTM_BLE_STATE_MASK request_state);
-extern void btm_ble_set_random_address(const RawAddress& random_bda);
extern void btm_ble_scanner_init(void);
extern void btm_ble_scanner_cleanup(void);
diff --git a/system/stack/btm/btm_inq.cc b/system/stack/btm/btm_inq.cc
index f53c679907..b0c8be4dff 100644
--- a/system/stack/btm/btm_inq.cc
+++ b/system/stack/btm/btm_inq.cc
@@ -545,7 +545,8 @@ tBTM_STATUS BTM_StartInquiry(tBTM_INQ_RESULTS_CB* p_results_cb,
btm_acl_update_inquiry_status(BTM_INQUIRY_STARTED);
if (p_inq->inq_active & BTM_SSP_INQUIRY_ACTIVE) {
- btm_process_inq_complete(BTM_NO_RESOURCES, BTM_GENERAL_INQUIRY);
+ btm_process_inq_complete(HCI_ERR_MAX_NUM_OF_CONNECTIONS,
+ BTM_GENERAL_INQUIRY);
return BTM_CMD_STARTED;
}
@@ -1261,7 +1262,7 @@ void btm_sort_inq_result(void) {
* Returns void
*
******************************************************************************/
-void btm_process_inq_complete(uint8_t status, uint8_t mode) {
+void btm_process_inq_complete(tHCI_STATUS status, uint8_t mode) {
tBTM_CMPL_CB* p_inq_cb = btm_cb.btm_inq_vars.p_inq_cmpl_cb;
tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
@@ -1324,7 +1325,7 @@ void btm_process_inq_complete(uint8_t status, uint8_t mode) {
* Returns void
*
******************************************************************************/
-void btm_process_cancel_complete(uint8_t status, uint8_t mode) {
+void btm_process_cancel_complete(tHCI_STATUS status, uint8_t mode) {
btm_acl_update_inquiry_status(BTM_INQUIRY_CANCELLED);
btm_process_inq_complete(status, mode);
}
@@ -1401,7 +1402,7 @@ tBTM_STATUS btm_initiate_rem_name(const RawAddress& remote_bda, uint8_t origin,
*
******************************************************************************/
void btm_process_remote_name(const RawAddress* bda, const BD_NAME bdn,
- uint16_t evt_len, uint8_t hci_status) {
+ uint16_t evt_len, tHCI_STATUS hci_status) {
tBTM_REMOTE_DEV_NAME rem_name;
tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
tBTM_CMPL_CB* p_cb = p_inq->p_remname_cmpl_cb;
diff --git a/system/stack/btm/btm_iso_impl.h b/system/stack/btm/btm_iso_impl.h
index 623696ac31..e9cd6e8287 100644
--- a/system/stack/btm/btm_iso_impl.h
+++ b/system/stack/btm/btm_iso_impl.h
@@ -93,7 +93,7 @@ struct iso_impl {
cig_create_cmpl_evt evt;
LOG_ASSERT(cig_callbacks_ != nullptr) << "Invalid CIG callbacks";
- LOG_ASSERT(len >= 3) << "Invalid packet length.";
+ LOG_ASSERT(len >= 3) << "Invalid packet length: " << +len;
STREAM_TO_UINT8(evt.status, stream);
STREAM_TO_UINT8(evt.cig_id, stream);
@@ -104,7 +104,7 @@ struct iso_impl {
if (evt.status == HCI_SUCCESS) {
LOG_ASSERT(len >= (3) + (cis_cnt * sizeof(uint16_t)))
- << "Invalid CIS count.";
+ << "Invalid CIS count: " << +cis_cnt;
/* Remove entries for the reconfigured CIG */
if (evt_code == kIsoEventCigOnReconfigureCmpl) {
@@ -138,7 +138,8 @@ struct iso_impl {
void create_cig(uint8_t cig_id,
struct iso_manager::cig_create_params cig_params) {
- LOG_ASSERT(!IsCigKnown(cig_id)) << "Invalid cig - already exists.";
+ LOG_ASSERT(!IsCigKnown(cig_id))
+ << "Invalid cig - already exists: " << +cig_id;
btsnd_hcic_set_cig_params(
cig_id, cig_params.sdu_itv_mtos, cig_params.sdu_itv_stom,
@@ -151,7 +152,7 @@ struct iso_impl {
void reconfigure_cig(uint8_t cig_id,
struct iso_manager::cig_create_params cig_params) {
- LOG_ASSERT(IsCigKnown(cig_id)) << "No such cig";
+ LOG_ASSERT(IsCigKnown(cig_id)) << "No such cig: " << +cig_id;
btsnd_hcic_set_cig_params(
cig_id, cig_params.sdu_itv_mtos, cig_params.sdu_itv_stom,
@@ -166,7 +167,7 @@ struct iso_impl {
cig_remove_cmpl_evt evt;
LOG_ASSERT(cig_callbacks_ != nullptr) << "Invalid CIG callbacks";
- LOG_ASSERT(len == 2) << "Invalid packet length.";
+ LOG_ASSERT(len == 2) << "Invalid packet length: " << +len;
STREAM_TO_UINT8(evt.status, stream);
STREAM_TO_UINT8(evt.cig_id, stream);
@@ -185,7 +186,7 @@ struct iso_impl {
}
void remove_cig(uint8_t cig_id) {
- LOG_ASSERT(IsCigKnown(cig_id)) << "No such cig";
+ LOG_ASSERT(IsCigKnown(cig_id)) << "No such cig: " << +cig_id;
btsnd_hcic_remove_cig(cig_id, base::BindOnce(&iso_impl::on_remove_cig,
base::Unretained(this)));
@@ -196,7 +197,7 @@ struct iso_impl {
uint16_t len) {
uint8_t status;
- LOG_ASSERT(len == 2) << "Invalid packet length: " << len;
+ LOG_ASSERT(len == 2) << "Invalid packet length: " << +len;
STREAM_TO_UINT16(status, stream);
@@ -205,7 +206,8 @@ struct iso_impl {
if (status != HCI_SUCCESS) {
auto cis = GetCisIfKnown(cis_param.cis_conn_handle);
- LOG_ASSERT(cis != nullptr) << "No such cis";
+ LOG_ASSERT(cis != nullptr)
+ << "No such cis: " << +cis_param.cis_conn_handle;
evt.status = status;
evt.cis_conn_hdl = cis_param.cis_conn_handle;
@@ -219,7 +221,7 @@ struct iso_impl {
void establish_cis(struct iso_manager::cis_establish_params conn_params) {
for (auto& el : conn_params.conn_pairs) {
auto cis = GetCisIfKnown(el.cis_conn_handle);
- LOG_ASSERT(cis) << "No such cis";
+ LOG_ASSERT(cis) << "No such cis: " << +el.cis_conn_handle;
LOG_ASSERT(!(cis->state_flags &
(kStateFlagIsConnected | kStateFlagIsConnecting)))
<< "Already connected or connecting";
@@ -233,7 +235,7 @@ struct iso_impl {
void disconnect_cis(uint16_t cis_handle, uint8_t reason) {
auto cis = GetCisIfKnown(cis_handle);
- LOG_ASSERT(cis) << "No such cis";
+ LOG_ASSERT(cis) << "No such cis: " << +cis_handle;
LOG_ASSERT(cis->state_flags & kStateFlagIsConnected ||
cis->state_flags & kStateFlagIsConnecting)
<< "Not connected";
@@ -314,7 +316,7 @@ struct iso_impl {
void remove_iso_data_path(uint16_t iso_handle, uint8_t data_path_dir) {
iso_base* iso = GetIsoIfKnown(iso_handle);
- LOG_ASSERT(iso != nullptr) << "No such iso connection";
+ LOG_ASSERT(iso != nullptr) << "No such iso connection: " << loghex(iso_handle);
LOG_ASSERT((iso->state_flags & kStateFlagHasDataPathSet) ==
kStateFlagHasDataPathSet)
<< "Data path not set";
@@ -371,7 +373,7 @@ struct iso_impl {
void read_iso_link_quality(uint16_t iso_handle) {
iso_base* iso = GetIsoIfKnown(iso_handle);
if (iso == nullptr) {
- LOG(ERROR) <<__func__ << "No such iso connection: " << +iso_handle;
+ LOG(ERROR) << __func__ << "No such iso connection: " << loghex(iso_handle);
return;
}
@@ -414,14 +416,17 @@ struct iso_impl {
uint16_t data_len) {
iso_base* iso = GetIsoIfKnown(iso_handle);
LOG_ASSERT(iso != nullptr)
- << "No such iso connection handle: " << +iso_handle;
+ << "No such iso connection handle: " << loghex(iso_handle);
if (!(iso->state_flags & kStateFlagIsBroadcast)) {
- LOG_ASSERT(iso->state_flags & kStateFlagIsConnected)
- << "CIS not established";
+ if (!(iso->state_flags & kStateFlagIsConnected)) {
+ LOG(WARNING) << __func__ << "Cis handle: " << loghex(iso_handle)
+ << " not established";
+ return;
+ }
}
LOG_ASSERT(iso->state_flags & kStateFlagHasDataPathSet)
- << "Data path not set for handle: " << +iso_handle;
+ << "Data path not set for handle: " << loghex(iso_handle);
/* Calculate sequence number for the ISO data packet.
* It should be incremented by 1 every SDU Interval.
@@ -449,14 +454,14 @@ struct iso_impl {
void process_cis_est_pkt(uint8_t len, uint8_t* data) {
cis_establish_cmpl_evt evt;
- LOG_ASSERT(len == 28) << "Invalid packet length";
+ LOG_ASSERT(len == 28) << "Invalid packet length: " << +len;
LOG_ASSERT(cig_callbacks_ != nullptr) << "Invalid CIG callbacks";
STREAM_TO_UINT8(evt.status, data);
STREAM_TO_UINT16(evt.cis_conn_hdl, data);
auto cis = GetCisIfKnown(evt.cis_conn_hdl);
- LOG_ASSERT(cis != nullptr) << "No such cis";
+ LOG_ASSERT(cis != nullptr) << "No such cis: " << +evt.cis_conn_hdl;
cis->sync_info.first_sync_ts = bluetooth::common::time_get_os_boottime_us();
@@ -558,7 +563,7 @@ struct iso_impl {
void process_create_big_cmpl_pkt(uint8_t len, uint8_t* data) {
struct big_create_cmpl_evt evt;
- LOG_ASSERT(len >= 18) << "Invalid packet length";
+ LOG_ASSERT(len >= 18) << "Invalid packet length: " << +len;
LOG_ASSERT(big_callbacks_ != nullptr) << "Invalid BIG callbacks";
STREAM_TO_UINT8(evt.status, data);
@@ -576,9 +581,9 @@ struct iso_impl {
uint8_t num_bis;
STREAM_TO_UINT8(num_bis, data);
- LOG_ASSERT(num_bis != 0) << "Invalid bis count";
+ LOG_ASSERT(num_bis != 0) << "Bis count is 0";
LOG_ASSERT(len == (18 + num_bis * sizeof(uint16_t)))
- << "Invalid packet length";
+ << "Invalid packet length: " << len << ". Number of bis: " << +num_bis;
uint32_t ts = bluetooth::common::time_get_os_boottime_us();
for (auto i = 0; i < num_bis; ++i) {
@@ -604,7 +609,7 @@ struct iso_impl {
void process_terminate_big_cmpl_pkt(uint8_t len, uint8_t* data) {
struct big_terminate_cmpl_evt evt;
- LOG_ASSERT(len == 2) << "Invalid packet length";
+ LOG_ASSERT(len == 2) << "Invalid packet length: " << +len;
LOG_ASSERT(big_callbacks_ != nullptr) << "Invalid BIG callbacks";
STREAM_TO_UINT8(evt.big_id, data);
@@ -621,12 +626,13 @@ struct iso_impl {
}
}
- LOG_ASSERT(is_known_handle) << "No such big";
+ LOG_ASSERT(is_known_handle) << "No such big: " << +evt.big_id;
big_callbacks_->OnBigEvent(kIsoEventBigOnTerminateCmpl, &evt);
}
void create_big(uint8_t big_id, struct big_create_params big_params) {
- LOG_ASSERT(!IsBigKnown(big_id)) << "Invalid big - already exists";
+ LOG_ASSERT(!IsBigKnown(big_id))
+ << "Invalid big - already exists: " << +big_id;
last_big_create_req_sdu_itv_ = big_params.sdu_itv;
btsnd_hcic_create_big(
@@ -637,7 +643,7 @@ struct iso_impl {
}
void terminate_big(uint8_t big_id, uint8_t reason) {
- LOG_ASSERT(IsBigKnown(big_id)) << "No such big";
+ LOG_ASSERT(IsBigKnown(big_id)) << "No such big: " << +big_id;
btsnd_hcic_term_big(big_id, reason);
}
diff --git a/system/stack/btu/btu_hcif.cc b/system/stack/btu/btu_hcif.cc
index 2d5abbfd92..7b6b876f7b 100644
--- a/system/stack/btu/btu_hcif.cc
+++ b/system/stack/btu/btu_hcif.cc
@@ -952,7 +952,7 @@ static void btu_hcif_inquiry_comp_evt(uint8_t* p) {
STREAM_TO_UINT8(status, p);
/* Tell inquiry processing that we are done */
- btm_process_inq_complete(status, BTM_BR_INQUIRY_MASK);
+ btm_process_inq_complete(to_hci_status_code(status), BTM_BR_INQUIRY_MASK);
}
/*******************************************************************************
@@ -1091,10 +1091,9 @@ static void btu_hcif_rmt_name_request_comp_evt(const uint8_t* p,
evt_len -= (1 + BD_ADDR_LEN);
- btm_process_remote_name(&bd_addr, p, evt_len, status);
+ btm_process_remote_name(&bd_addr, p, evt_len, to_hci_status_code(status));
- btm_sec_rmt_name_request_complete(&bd_addr, p,
- static_cast<tHCI_STATUS>(status));
+ btm_sec_rmt_name_request_complete(&bd_addr, p, to_hci_status_code(status));
}
constexpr uint8_t MIN_KEY_SIZE = 7;
@@ -1423,7 +1422,8 @@ static void btu_hcif_hdl_command_status(uint16_t opcode, uint8_t status,
case HCI_INQUIRY:
if (status != HCI_SUCCESS) {
// Tell inquiry processing that we are done
- btm_process_inq_complete(status, BTM_BR_INQUIRY_MASK);
+ btm_process_inq_complete(to_hci_status_code(status),
+ BTM_BR_INQUIRY_MASK);
}
break;
case HCI_SWITCH_ROLE:
@@ -1460,9 +1460,10 @@ static void btu_hcif_hdl_command_status(uint16_t opcode, uint8_t status,
case HCI_RMT_NAME_REQUEST:
if (status != HCI_SUCCESS) {
// Tell inquiry processing that we are done
- btm_process_remote_name(nullptr, nullptr, 0, status);
+ btm_process_remote_name(nullptr, nullptr, 0,
+ to_hci_status_code(status));
btm_sec_rmt_name_request_complete(nullptr, nullptr,
- static_cast<tHCI_STATUS>(status));
+ to_hci_status_code(status));
}
break;
case HCI_READ_RMT_EXT_FEATURES:
diff --git a/system/stack/eatt/eatt.h b/system/stack/eatt/eatt.h
index d2071ab7a1..2eac63118d 100644
--- a/system/stack/eatt/eatt.h
+++ b/system/stack/eatt/eatt.h
@@ -99,6 +99,9 @@ class EattChannel {
class EattExtension {
public:
EattExtension();
+ EattExtension(const EattExtension&) = delete;
+ EattExtension& operator=(const EattExtension&) = delete;
+
virtual ~EattExtension();
static EattExtension* GetInstance() {
@@ -277,8 +280,6 @@ class EattExtension {
private:
struct impl;
std::unique_ptr<impl> pimpl_;
-
- DISALLOW_COPY_AND_ASSIGN(EattExtension);
};
} // namespace eatt
diff --git a/system/stack/hcic/hcicmds.cc b/system/stack/hcic/hcicmds.cc
index fa5ea76e43..49f68001be 100644
--- a/system/stack/hcic/hcicmds.cc
+++ b/system/stack/hcic/hcicmds.cc
@@ -421,6 +421,8 @@ void bte_main_hci_send(BT_HDR* p_msg, uint16_t event);
#define HCI_WRITE_IAC_LAP_LAP_OFF 1
/* Write Current IAC LAP */
+#define HCIC_PARAM_SIZE_CONFIGURE_DATA_PATH 3
+
/*******************************************************************************
* BLE Commands
* Note: "local_controller_id" is for transport, not counted in HCI
@@ -1880,11 +1882,11 @@ void btsnd_hcic_configure_data_path(uint8_t data_path_direction,
BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
uint8_t* pp = (uint8_t*)(p + 1);
uint8_t size = static_cast<uint8_t>(vendor_config.size());
- p->len = HCIC_PREAMBLE_SIZE + 3 + size;
+ p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CONFIGURE_DATA_PATH + size;
p->offset = 0;
UINT16_TO_STREAM(pp, HCI_CONFIGURE_DATA_PATH);
- UINT8_TO_STREAM(pp, p->len);
+ UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CONFIGURE_DATA_PATH + size);
UINT8_TO_STREAM(pp, data_path_direction);
UINT8_TO_STREAM(pp, data_path_id);
UINT8_TO_STREAM(pp, vendor_config.size());
@@ -1899,170 +1901,9 @@ bluetooth::legacy::hci::Interface interface_ = {
// LINK_CONTROL
.StartInquiry = btsnd_hcic_inquiry, // OCF 0x0401
.InquiryCancel = btsnd_hcic_inq_cancel, // OCF 0x0402
- .StartPeriodicInquiryMode = btsnd_hcic_per_inq_mode, // OCF 0x0403
- .ExitPeriodicInquiryMode = btsnd_hcic_exit_per_inq, // OCF 0x0404
- .CreateConnection = btsnd_hcic_create_conn, // OCF 0x0405
.Disconnect = btsnd_hcic_disconnect, // OCF 0x0406
- // UNUSED OCF 0x0407 btsnd_hcic_add_SCO_conn
- .CreateConnectionCancel = btsnd_hcic_create_conn_cancel, // OCF 0x0408
- .AcceptConnectionRequest = btsnd_hcic_accept_conn, // OCF 0x0409
- .RejectConnectionRequest = btsnd_hcic_reject_conn, // OCF 0x040A
- .LinkKeyRequestReply = btsnd_hcic_link_key_req_reply, // OCF 0x040B
- .LinkKeyRequestNegativeReply =
- btsnd_hcic_link_key_neg_reply, // OCF 0x040C,
- .PinCodeRequestReply = btsnd_hcic_pin_code_req_reply, // OCF 0x040D,
- .PinCodeRequestNegativeReply =
- btsnd_hcic_pin_code_neg_reply, // OCF 0x040E,
.ChangeConnectionPacketType = btsnd_hcic_change_conn_type, // OCF 0x040F,
- // UNUSED OCF 0x0410
- .AuthenticationRequested = btsnd_hcic_auth_request, // OCF 0x0411,
- // UNUSED OCF 0x0412
- .SetConnectionEncryption = btsnd_hcic_set_conn_encrypt, // OCF 0x0413,
- // UNUSED OCF 0x0414
- .ChangeConnectionLinkKey = nullptr, // OCF 0x0415,
- // UNUSED OCF 0x0416
- .CentralLinkKey = nullptr, // OCF 0x0417,
- // UNUSED OCF 0x0418
- .RemoteNameRequest = btsnd_hcic_rmt_name_req, // OCF 0x0419,
- .RemoteNameRequestCancel = btsnd_hcic_rmt_name_req_cancel, // OCF 0x041A,
- .ReadRemoteSupportedFeatures = btsnd_hcic_rmt_features_req, // OCF 0x041B,
- .ReadRemoteExtendedFeatures = btsnd_hcic_rmt_ext_features, // OCF 0x041C,
- .ReadRemoteVersionInformation = btsnd_hcic_rmt_ver_req, // OCF 0x041D,
- // UNUSED OCF 0x041E
- .ReadClockOffset = btsnd_hcic_read_rmt_clk_offset, // OCF 0x041F,
- .ReadLmpHandle = btsnd_hcic_read_lmp_handle, // OCF 0x0420,
- // UNUSED OCF 0x0420 - 0x0427
- .SetupSynchronousConnection = btsnd_hcic_setup_esco_conn, // OCF 0x0428,
- .AcceptSynchronousConnection = btsnd_hcic_accept_esco_conn, // OCF 0x0429,
- .RejectSynchronousConnection = btsnd_hcic_reject_esco_conn, // OCF 0x042A,
- .IoCapabilityRequestReply = btsnd_hcic_io_cap_req_reply, // OCF 0x042B,
- .UserConfirmationRequestReply = btsnd_hcic_user_conf_reply, // OCF 0x042C,
- .UserConfirmationRequestNegativeReply =
- btsnd_hcic_user_conf_reply, // OCF 0x042D,
- .UserPasskeyRequestReply = btsnd_hcic_user_passkey_reply, // OCF 0x042E,
- .UserPasskeyRequestNegativeReply =
- btsnd_hcic_user_passkey_neg_reply, // OCF 0x042F,
- .RemoteOobDataRequestReply = btsnd_hcic_rem_oob_reply, // OCF 0x0430,
- // UNUSED OCF 0x0431 - 0x0432
- .RemoteOobDataRequestNegativeReply =
- btsnd_hcic_rem_oob_neg_reply, // OCF 0x0433,
- .IoCapabilityRequestNegativeReply =
- btsnd_hcic_io_cap_req_neg_reply, // OCF 0x0434,
- // UNUSED OCF 0x0435 - 0x043C
- .EnhancedSetupSynchronousConnection =
- btsnd_hcic_enhanced_set_up_synchronous_connection, // OCF 0x043D,
- .EnhancedAcceptSynchronousConnection =
- btsnd_hcic_enhanced_accept_synchronous_connection, // OCF 0x043E,
- // UNUSED OCF 0x043F - 0x0444
- .RemoteOobExtendedDataRequestReply = nullptr, // OCF 0x0445,
-
- // LINK_POLICY
- .HoldMode = btsnd_hcic_hold_mode, // OCF 0x0801,
- // UNUSED OCF 0x0802
- .SniffMode = btsnd_hcic_sniff_mode, // OCF 0x0803,
- .ExitSniffMode = btsnd_hcic_exit_sniff_mode, // OCF 0x0804,
- // UNUSED OCF 0x0805 - 0x0806
- .QosSetup = btsnd_hcic_qos_setup, // OCF 0x0807,
- // UNUSED OCF 0x0808
- .RoleDiscovery = nullptr, // OCF 0x0809,
- // UNUSED OCF 0x080A
.StartRoleSwitch = btsnd_hcic_switch_role, // OCF 0x080B,
- .ReadLinkPolicySettings = nullptr, // OCF 0x080C,
- .WriteLinkPolicySettings = btsnd_hcic_write_policy_set, // OCF 0x080D,
- .ReadDefaultLinkPolicySettings = nullptr, // OCF 0x080E,
- .WriteDefaultLinkPolicySettings =
- btsnd_hcic_write_def_policy_set, // OCF 0x080F,
- .FlowSpecification = nullptr, // OCF 0x0810,
- .SniffSubrating = btsnd_hcic_sniff_sub_rate, // OCF 0x0811,
-
- // CONTROLLER_AND_BASEBAND
- .SetEventMask = nullptr, // OCF 0x0C01,
- // UNUSED OCF 0x0C02
- .Reset = nullptr, // OCF 0x0C03,
- // UNUSED OCF 0x0C04
- .SetEventFilter = btsnd_hcic_set_event_filter, // OCF 0x0C05,
- // UNUSED OCF 0x0C06 = 0x0C07
- .Flush = nullptr, // OCF 0x0C08,
- .ReadPinType = nullptr, // OCF 0x0C09,
- .WritePinType = btsnd_hcic_write_pin_type, // OCF 0x0C0A,
- .CreateNewUnitKey = nullptr, // OCF 0x0C0B,
- // UNUSED OCF 0x0C0C
- .ReadStoredLinkKey = nullptr, // OCF 0x0C0D,
- // UNUSED OCF 0x0C0E - 0x0C10
- .WriteStoredLinkKey = nullptr, // OCF 0x0C11,
- .DeleteStoredLinkKey = btsnd_hcic_delete_stored_key, // OCF 0x0C12,
- .WriteLocalName = btsnd_hcic_change_name, // OCF 0x0C13,
- .ReadLocalName = btsnd_hcic_read_name, // OCF 0x0C14,
- .ReadConnectionAcceptTimeout = nullptr, // OCF 0x0C15,
- .WriteConnectionAcceptTimeout = btsnd_hcic_write_page_tout, // OCF 0x0C16,
- .ReadPageTimeout = nullptr, // OCF 0x0C17,
- .WritePageTimeout = nullptr, // OCF 0x0C18,
- .ReadScanEnable = nullptr, // OCF 0x0C19,
- .WriteScanEnable = btsnd_hcic_write_scan_enable, // OCF 0x0C1A,
- .ReadPageScanActivity = nullptr, // OCF 0x0C1B,
- .WritePageScanActivity = btsnd_hcic_write_pagescan_cfg, // OCF 0x0C1C,
- .ReadInquiryScanActivity = nullptr, // OCF 0x0C1D,
- .WriteInquiryScanActivity = btsnd_hcic_write_inqscan_cfg, // OCF 0x0C1E,
- .ReadAuthenticationEnable = nullptr, // OCF 0x0C1F,
- // UNUSED OCF 0x0C20 - 0x0C22
- .ReadClassOfDevice = nullptr, // OCF 0x0C23,
- .WriteClassOfDevice = btsnd_hcic_write_dev_class, // OCF 0x0C24,
- .ReadVoiceSetting = nullptr, // OCF 0x0C25,
- .WriteVoiceSetting = btsnd_hcic_write_voice_settings, // OCF 0x0C26,
- .ReadAutomaticFlushTimeout =
- btsnd_hcic_read_automatic_flush_timeout, // OCF 0x0C27,
- .WriteAutomaticFlushTimeout =
- btsnd_hcic_write_auto_flush_tout, // OCF 0x0C28,
- .ReadNumBroadcastRetransmits = nullptr, // OCF 0x0C29,
- .WriteNumBroadcastRetransmits = nullptr, // OCF 0x0C2A,
- .ReadHoldModeActivity = nullptr, // OCF 0x0C2B,
- .WriteHoldModeActivity = nullptr, // OCF 0x0C2C,
- .ReadTransmitPowerLevel = btsnd_hcic_read_tx_power, // OCF 0x0C2D,
- .ReadSynchronousFlowControlEnable = nullptr, // OCF 0x0C2E,
- .WriteSynchronousFlowControlEnable = nullptr, // OCF 0x0C2F,
- // UNUSED OCF 0x0C30
- .SetControllerToHostFlowControl = nullptr, // OCF 0x0C31,
- // UNUSED OCF 0x0C32
- .HostBufferSize = nullptr, // OCF 0x0C33,
- // UNUSED OCF 0x0C34
- .HostNumCompletedPackets = nullptr, // OCF 0x0C35,
- .ReadLinkSupervisionTimeout =
- btsnd_hcic_write_link_super_tout, // OCF 0x0C36,
- .WriteLinkSupervisionTimeout = nullptr, // OCF 0x0C37,
- .ReadNumberOfSupportedIac = nullptr, // OCF 0x0C38,
- .ReadCurrentIacLap = nullptr, // OCF 0x0C39,
- .WriteCurrentIacLap = btsnd_hcic_write_cur_iac_lap, // OCF 0x0C3A,
- .SetAfhHostChannelClassification = nullptr, // OCF 0x0C3F,
- .ReadInquiryScanType = nullptr, // OCF 0x0C42,
- .WriteInquiryScanType = btsnd_hcic_write_inqscan_type, // OCF 0x0C43,
- .ReadInquiryMode = nullptr, // OCF 0x0C44,
- .WriteInquiryMode = btsnd_hcic_write_inquiry_mode, // OCF 0x0C45,
- .ReadPageScanType = nullptr, // OCF 0x0C46,
- .WritePageScanType = btsnd_hcic_write_pagescan_type, // OCF 0x0C47,
- .ReadAfhChannelAssessmentMode = nullptr, // OCF 0x0C48,
- .WriteAfhChannelAssessmentMode = nullptr, // OCF 0x0C49,
- .ReadExtendedInquiryResponse = nullptr, // OCF 0x0C51,
- .WriteExtendedInquiryResponse =
- btsnd_hcic_write_ext_inquiry_response, // OCF 0x0C52,
- .RefreshEncryptionKey = nullptr, // OCF 0x0C53,
- .ReadSimplePairingMode = nullptr, // OCF 0x0C55,
- .WriteSimplePairingMode = nullptr, // OCF 0x0C56,
- .ReadLocalOobData = btsnd_hcic_read_local_oob_data, // OCF 0x0C57,
- .ReadInquiryResponseTransmitPowerLevel = nullptr, // OCF 0x0C58,
- .WriteInquiryTransmitPowerLevel = nullptr, // OCF 0x0C59,
- .EnhancedFlush = btsnd_hcic_enhanced_flush, // OCF 0x0C5F,
- .SendKeypressNotification = btsnd_hcic_send_keypress_notif, // OCF 0x0C60,
-
- // STATUS_PARAMETERS
- .ReadFailedContactCounter =
- btsnd_hcic_read_failed_contact_counter, // OCF 0x1401,
- .ResetFailedContactCounter = nullptr, // OCF 0x1402,
- .ReadLinkQuality = btsnd_hcic_get_link_quality, // OCF 0x1403,
- // UNUSED OCF 0x1404
- .ReadRssi = btsnd_hcic_read_rssi, // OCF 0x1405,
- .ReadAfhChannelMap = nullptr, // OCF 0x1406,
- .ReadClock = nullptr, // OCF 0x1407,
- .ReadEncryptionKeySize = nullptr, // OCF 0x1408,
};
const bluetooth::legacy::hci::Interface&
diff --git a/system/stack/include/bt_dev_class.h b/system/stack/include/bt_dev_class.h
index a141c26863..e0a6305995 100644
--- a/system/stack/include/bt_dev_class.h
+++ b/system/stack/include/bt_dev_class.h
@@ -29,6 +29,99 @@ typedef uint8_t DEV_CLASS[DEV_CLASS_LEN]; /* Device class */
inline constexpr DEV_CLASS kDevClassEmpty = {};
#endif // __cplusplus
+/* 0x00 is used as unclassified for all minor device classes */
+#define BTM_COD_MINOR_UNCLASSIFIED 0x00
+#define BTM_COD_MINOR_WEARABLE_HEADSET 0x04
+#define BTM_COD_MINOR_CONFM_HANDSFREE 0x08
+#define BTM_COD_MINOR_CAR_AUDIO 0x20
+#define BTM_COD_MINOR_SET_TOP_BOX 0x24
+
+/* minor device class field for Peripheral Major Class */
+/* Bits 6-7 independently specify mouse, keyboard, or combo mouse/keyboard */
+#define BTM_COD_MINOR_KEYBOARD 0x40
+#define BTM_COD_MINOR_POINTING 0x80
+/* Bits 2-5 OR'd with selection from bits 6-7 */
+/* #define BTM_COD_MINOR_UNCLASSIFIED 0x00 */
+#define BTM_COD_MINOR_JOYSTICK 0x04
+#define BTM_COD_MINOR_GAMEPAD 0x08
+#define BTM_COD_MINOR_REMOTE_CONTROL 0x0C
+#define BTM_COD_MINOR_DIGITIZING_TABLET 0x14
+#define BTM_COD_MINOR_CARD_READER 0x18 /* e.g. SIM card reader */
+#define BTM_COD_MINOR_DIGITAL_PAN 0x1C
+
+/* minor device class field for Imaging Major Class */
+/* Bits 5-7 independently specify display, camera, scanner, or printer */
+#define BTM_COD_MINOR_DISPLAY 0x10
+/* Bits 2-3 Reserved */
+/* #define BTM_COD_MINOR_UNCLASSIFIED 0x00 */
+
+/* minor device class field for Wearable Major Class */
+/* Bits 2-7 meaningful */
+#define BTM_COD_MINOR_WRIST_WATCH 0x04
+#define BTM_COD_MINOR_GLASSES 0x14
+
+/* minor device class field for Health Major Class */
+/* Bits 2-7 meaningful */
+#define BTM_COD_MINOR_BLOOD_MONITOR 0x04
+#define BTM_COD_MINOR_THERMOMETER 0x08
+#define BTM_COD_MINOR_WEIGHING_SCALE 0x0C
+#define BTM_COD_MINOR_GLUCOSE_METER 0x10
+#define BTM_COD_MINOR_PULSE_OXIMETER 0x14
+#define BTM_COD_MINOR_HEART_PULSE_MONITOR 0x18
+#define BTM_COD_MINOR_STEP_COUNTER 0x20
+
+/***************************
+ * major device class field
+ ***************************/
+#define BTM_COD_MAJOR_COMPUTER 0x01
+#define BTM_COD_MAJOR_PHONE 0x02
+#define BTM_COD_MAJOR_AUDIO 0x04
+#define BTM_COD_MAJOR_PERIPHERAL 0x05
+#define BTM_COD_MAJOR_IMAGING 0x06
+#define BTM_COD_MAJOR_WEARABLE 0x07
+#define BTM_COD_MAJOR_HEALTH 0x09
+#define BTM_COD_MAJOR_UNCLASSIFIED 0x1F
+
+/***************************
+ * service class fields
+ ***************************/
+#define BTM_COD_SERVICE_LMTD_DISCOVER 0x0020
+#define BTM_COD_SERVICE_LE_AUDIO 0x0040
+#define BTM_COD_SERVICE_POSITIONING 0x0100
+#define BTM_COD_SERVICE_NETWORKING 0x0200
+#define BTM_COD_SERVICE_RENDERING 0x0400
+#define BTM_COD_SERVICE_CAPTURING 0x0800
+#define BTM_COD_SERVICE_OBJ_TRANSFER 0x1000
+#define BTM_COD_SERVICE_AUDIO 0x2000
+#define BTM_COD_SERVICE_TELEPHONY 0x4000
+#define BTM_COD_SERVICE_INFORMATION 0x8000
+
+/* class of device field macros */
+#define BTM_COD_MINOR_CLASS(u8, pd) \
+ { (u8) = (pd)[2] & 0xFC; }
+#define BTM_COD_MAJOR_CLASS(u8, pd) \
+ { (u8) = (pd)[1] & 0x1F; }
+#define BTM_COD_SERVICE_CLASS(u16, pd) \
+ { \
+ (u16) = (pd)[0]; \
+ (u16) <<= 8; \
+ (u16) += (pd)[1] & 0xE0; \
+ }
+
+/* to set the fields (assumes that format type is always 0) */
+#define FIELDS_TO_COD(pd, mn, mj, sv) \
+ { \
+ (pd)[2] = mn; \
+ (pd)[1] = (mj) + ((sv)&BTM_COD_SERVICE_CLASS_LO_B); \
+ (pd)[0] = (sv) >> 8; \
+ }
+
+/* the COD masks */
+#define BTM_COD_MINOR_CLASS_MASK 0xFC
+#define BTM_COD_MAJOR_CLASS_MASK 0x1F
+#define BTM_COD_SERVICE_CLASS_LO_B 0x00E0
+#define BTM_COD_SERVICE_CLASS_MASK 0xFFE0
+
#define DEVCLASS_TO_STREAM(p, a) \
{ \
int ijk; \
diff --git a/system/stack/include/btm_api_types.h b/system/stack/include/btm_api_types.h
index 9999eafc10..981347ff4e 100644
--- a/system/stack/include/btm_api_types.h
+++ b/system/stack/include/btm_api_types.h
@@ -75,99 +75,6 @@ typedef void(tBTM_VSC_CMPL_CB)(tBTM_VSC_CMPL* p1);
* minor device class field
****************************/
-/* 0x00 is used as unclassified for all minor device classes */
-#define BTM_COD_MINOR_UNCLASSIFIED 0x00
-#define BTM_COD_MINOR_WEARABLE_HEADSET 0x04
-#define BTM_COD_MINOR_CONFM_HANDSFREE 0x08
-#define BTM_COD_MINOR_CAR_AUDIO 0x20
-#define BTM_COD_MINOR_SET_TOP_BOX 0x24
-
-/* minor device class field for Peripheral Major Class */
-/* Bits 6-7 independently specify mouse, keyboard, or combo mouse/keyboard */
-#define BTM_COD_MINOR_KEYBOARD 0x40
-#define BTM_COD_MINOR_POINTING 0x80
-/* Bits 2-5 OR'd with selection from bits 6-7 */
-/* #define BTM_COD_MINOR_UNCLASSIFIED 0x00 */
-#define BTM_COD_MINOR_JOYSTICK 0x04
-#define BTM_COD_MINOR_GAMEPAD 0x08
-#define BTM_COD_MINOR_REMOTE_CONTROL 0x0C
-#define BTM_COD_MINOR_DIGITIZING_TABLET 0x14
-#define BTM_COD_MINOR_CARD_READER 0x18 /* e.g. SIM card reader */
-#define BTM_COD_MINOR_DIGITAL_PAN 0x1C
-
-/* minor device class field for Imaging Major Class */
-/* Bits 5-7 independently specify display, camera, scanner, or printer */
-#define BTM_COD_MINOR_DISPLAY 0x10
-/* Bits 2-3 Reserved */
-/* #define BTM_COD_MINOR_UNCLASSIFIED 0x00 */
-
-/* minor device class field for Wearable Major Class */
-/* Bits 2-7 meaningful */
-#define BTM_COD_MINOR_WRIST_WATCH 0x04
-#define BTM_COD_MINOR_GLASSES 0x14
-
-/* minor device class field for Health Major Class */
-/* Bits 2-7 meaningful */
-#define BTM_COD_MINOR_BLOOD_MONITOR 0x04
-#define BTM_COD_MINOR_THERMOMETER 0x08
-#define BTM_COD_MINOR_WEIGHING_SCALE 0x0C
-#define BTM_COD_MINOR_GLUCOSE_METER 0x10
-#define BTM_COD_MINOR_PULSE_OXIMETER 0x14
-#define BTM_COD_MINOR_HEART_PULSE_MONITOR 0x18
-#define BTM_COD_MINOR_STEP_COUNTER 0x20
-
-/***************************
- * major device class field
- ***************************/
-#define BTM_COD_MAJOR_COMPUTER 0x01
-#define BTM_COD_MAJOR_PHONE 0x02
-#define BTM_COD_MAJOR_AUDIO 0x04
-#define BTM_COD_MAJOR_PERIPHERAL 0x05
-#define BTM_COD_MAJOR_IMAGING 0x06
-#define BTM_COD_MAJOR_WEARABLE 0x07
-#define BTM_COD_MAJOR_HEALTH 0x09
-#define BTM_COD_MAJOR_UNCLASSIFIED 0x1F
-
-/***************************
- * service class fields
- ***************************/
-#define BTM_COD_SERVICE_LMTD_DISCOVER 0x0020
-#define BTM_COD_SERVICE_LE_AUDIO 0x0040
-#define BTM_COD_SERVICE_POSITIONING 0x0100
-#define BTM_COD_SERVICE_NETWORKING 0x0200
-#define BTM_COD_SERVICE_RENDERING 0x0400
-#define BTM_COD_SERVICE_CAPTURING 0x0800
-#define BTM_COD_SERVICE_OBJ_TRANSFER 0x1000
-#define BTM_COD_SERVICE_AUDIO 0x2000
-#define BTM_COD_SERVICE_TELEPHONY 0x4000
-#define BTM_COD_SERVICE_INFORMATION 0x8000
-
-/* class of device field macros */
-#define BTM_COD_MINOR_CLASS(u8, pd) \
- { (u8) = (pd)[2] & 0xFC; }
-#define BTM_COD_MAJOR_CLASS(u8, pd) \
- { (u8) = (pd)[1] & 0x1F; }
-#define BTM_COD_SERVICE_CLASS(u16, pd) \
- { \
- (u16) = (pd)[0]; \
- (u16) <<= 8; \
- (u16) += (pd)[1] & 0xE0; \
- }
-
-/* to set the fields (assumes that format type is always 0) */
-#define FIELDS_TO_COD(pd, mn, mj, sv) \
- { \
- (pd)[2] = mn; \
- (pd)[1] = (mj) + ((sv)&BTM_COD_SERVICE_CLASS_LO_B); \
- (pd)[0] = (sv) >> 8; \
- }
-
-/* the COD masks */
-#define BTM_COD_MINOR_CLASS_MASK 0xFC
-#define BTM_COD_MAJOR_CLASS_MASK 0x1F
-#define BTM_COD_SERVICE_CLASS_LO_B 0x00E0
-#define BTM_COD_SERVICE_CLASS_MASK 0xFFE0
-
/* BTM service definitions
* Used for storing EIR data to bit mask
*/
diff --git a/system/stack/include/hcimsgs.h b/system/stack/include/hcimsgs.h
index 2202d89efc..95ef118272 100644
--- a/system/stack/include/hcimsgs.h
+++ b/system/stack/include/hcimsgs.h
@@ -65,167 +65,9 @@ struct Interface {
void (*StartInquiry)(const LAP inq_lap, uint8_t duration,
uint8_t response_cnt);
void (*InquiryCancel)();
- void (*StartPeriodicInquiryMode)(uint16_t max_period, uint16_t min_period,
- const LAP inq_lap, uint8_t duration,
- uint8_t response_cnt);
- void (*ExitPeriodicInquiryMode)();
- void (*CreateConnection)(const RawAddress& dest, uint16_t packet_types,
- uint8_t page_scan_rep_mode, uint8_t page_scan_mode,
- uint16_t clock_offset, uint8_t allow_switch);
void (*Disconnect)(uint16_t handle, uint8_t reason);
- // UNUSED 0x0407 btsnd_hcic_add_SCO_conn
- void (*CreateConnectionCancel)(const RawAddress& dest);
- void (*AcceptConnectionRequest)(const RawAddress& dest, uint8_t role);
- void (*RejectConnectionRequest)(const RawAddress& dest, uint8_t reason);
- void (*LinkKeyRequestReply)(const RawAddress& bd_addr,
- const LinkKey& link_key);
- void (*LinkKeyRequestNegativeReply)(const RawAddress& bd_addr);
- void (*PinCodeRequestReply)(const RawAddress& bd_addr, uint8_t pin_code_len,
- PIN_CODE pin_code);
- void (*PinCodeRequestNegativeReply)(const RawAddress& bd_addr);
void (*ChangeConnectionPacketType)(uint16_t handle, uint16_t packet_types);
- void (*AuthenticationRequested)(uint16_t handle);
- void (*SetConnectionEncryption)(uint16_t handle, bool enable);
- void (*ChangeConnectionLinkKey)(); // 0x0415,
- // UNUSED 0x0416
- void (*CentralLinkKey)(); // 0x0417,
- void (*RemoteNameRequest)(const RawAddress& bd_addr,
- uint8_t page_scan_rep_mode, uint8_t page_scan_mode,
- uint16_t clock_offset);
- void (*RemoteNameRequestCancel)(const RawAddress& bd_addr);
- void (*ReadRemoteSupportedFeatures)(uint16_t handle);
- void (*ReadRemoteExtendedFeatures)(uint16_t handle, uint8_t page_num);
- void (*ReadRemoteVersionInformation)(uint16_t handle);
- void (*ReadClockOffset)(uint16_t handle);
- void (*ReadLmpHandle)(uint16_t handle);
- void (*SetupSynchronousConnection)(uint16_t handle,
- uint32_t transmit_bandwidth,
- uint32_t receive_bandwidth,
- uint16_t max_latency, uint16_t voice,
- uint8_t retrans_effort,
- uint16_t packet_types);
- void (*AcceptSynchronousConnection)(
- const RawAddress& bd_addr, uint32_t transmit_bandwidth,
- uint32_t receive_bandwidth, uint16_t max_latency, uint16_t content_fmt,
- uint8_t retrans_effort, uint16_t packet_types);
- void (*RejectSynchronousConnection)(const RawAddress& bd_addr,
- uint8_t reason);
- void (*IoCapabilityRequestReply)(const RawAddress& bd_addr,
- uint8_t capability, uint8_t oob_present,
- uint8_t auth_req);
- void (*UserConfirmationRequestReply)(const RawAddress& bd_addr, bool is_yes);
- void (*UserConfirmationRequestNegativeReply)(const RawAddress& bd_addr,
- bool is_yes);
- void (*UserPasskeyRequestReply)(const RawAddress& bd_addr, uint32_t value);
- void (*UserPasskeyRequestNegativeReply)(const RawAddress& bd_addr);
- void (*RemoteOobDataRequestReply)(const RawAddress& bd_addr, const Octet16& c,
- const Octet16& r);
- void (*RemoteOobDataRequestNegativeReply)(const RawAddress& bd_addr);
- void (*IoCapabilityRequestNegativeReply)(const RawAddress& bd_addr,
- uint8_t err_code);
- void (*EnhancedSetupSynchronousConnection)(uint16_t conn_handle,
- enh_esco_params_t* p_params);
- void (*EnhancedAcceptSynchronousConnection)(const RawAddress& bd_addr,
- enh_esco_params_t* p_params);
- void (*RemoteOobExtendedDataRequestReply)();
-
- // LINK_POLICY 0x08xx
- void (*HoldMode)(uint16_t handle, uint16_t max_hold_period,
- uint16_t min_hold_period);
- void (*SniffMode)(uint16_t handle, uint16_t max_sniff_period,
- uint16_t min_sniff_period, uint16_t sniff_attempt,
- uint16_t sniff_timeout);
- void (*ExitSniffMode)(uint16_t handle);
- void (*QosSetup)(uint16_t handle, uint8_t flags, uint8_t service_type,
- uint32_t token_rate, uint32_t peak, uint32_t latency,
- uint32_t delay_var);
- // UNUSED 0x0808
- void (*RoleDiscovery)();
void (*StartRoleSwitch)(const RawAddress& bd_addr, uint8_t role);
- void (*ReadLinkPolicySettings)();
- void (*WriteLinkPolicySettings)(uint16_t handle, uint16_t settings);
- void (*ReadDefaultLinkPolicySettings)();
- void (*WriteDefaultLinkPolicySettings)(uint16_t settings);
- void (*FlowSpecification)();
- void (*SniffSubrating)(uint16_t handle, uint16_t max_lat,
- uint16_t min_remote_lat, uint16_t min_local_lat);
-
- // CONTROLLER_AND_BASEBAND 0x0Cxx
- void (*SetEventMask)();
- void (*Reset)();
- void (*SetEventFilter)(uint8_t filt_type, uint8_t filt_cond_type,
- uint8_t* filt_cond, uint8_t filt_cond_len);
- void (*Flush)();
- void (*ReadPinType)();
- void (*WritePinType)(uint8_t type);
- void (*CreateNewUnitKey)();
- void (*ReadStoredLinkKey)();
- void (*WriteStoredLinkKey)();
- void (*DeleteStoredLinkKey)(const RawAddress& bd_addr, bool delete_all_flag);
- void (*WriteLocalName)(BD_NAME name);
- void (*ReadLocalName)();
- void (*ReadConnectionAcceptTimeout)();
- void (*WriteConnectionAcceptTimeout)(uint16_t timeout);
- void (*ReadPageTimeout)();
- void (*WritePageTimeout)();
- void (*ReadScanEnable)();
- void (*WriteScanEnable)(uint8_t flag);
- void (*ReadPageScanActivity)();
- void (*WritePageScanActivity)(uint16_t interval, uint16_t window);
- void (*ReadInquiryScanActivity)();
- void (*WriteInquiryScanActivity)(uint16_t interval, uint16_t window);
- void (*ReadAuthenticationEnable)();
- void (*WriteAuthenticationEnable)(uint8_t flag);
- void (*ReadClassOfDevice)();
- void (*WriteClassOfDevice)(DEV_CLASS dev_class);
- void (*ReadVoiceSetting)();
- void (*WriteVoiceSetting)(uint16_t flags);
- void (*ReadAutomaticFlushTimeout)(uint16_t handle);
- void (*WriteAutomaticFlushTimeout)(uint16_t handle, uint16_t tout);
- void (*ReadNumBroadcastRetransmits)();
- void (*WriteNumBroadcastRetransmits)();
- void (*ReadHoldModeActivity)();
- void (*WriteHoldModeActivity)();
- void (*ReadTransmitPowerLevel)(uint16_t handle, uint8_t type);
- void (*ReadSynchronousFlowControlEnable)();
- void (*WriteSynchronousFlowControlEnable)();
- void (*SetControllerToHostFlowControl)();
- void (*HostBufferSize)();
- void (*HostNumCompletedPackets)();
- void (*ReadLinkSupervisionTimeout)(uint16_t handle, uint16_t timeout);
- void (*WriteLinkSupervisionTimeout)();
- void (*ReadNumberOfSupportedIac)();
- void (*ReadCurrentIacLap)();
- void (*WriteCurrentIacLap)(uint8_t num_cur_iac, LAP* const iac_lap);
- void (*SetAfhHostChannelClassification)();
- void (*ReadInquiryScanType)();
- void (*WriteInquiryScanType)(uint8_t type);
- void (*ReadInquiryMode)(); // 0x0C44,
- void (*WriteInquiryMode)(uint8_t mode);
- void (*ReadPageScanType)(); // 0x0C46,
- void (*WritePageScanType)(uint8_t type);
- void (*ReadAfhChannelAssessmentMode)();
- void (*WriteAfhChannelAssessmentMode)();
- void (*ReadExtendedInquiryResponse)();
- void (*WriteExtendedInquiryResponse)(void* buffer, uint8_t fec_req);
- void (*RefreshEncryptionKey)();
- void (*ReadSimplePairingMode)();
- void (*WriteSimplePairingMode)();
- void (*ReadLocalOobData)();
- void (*ReadInquiryResponseTransmitPowerLevel)();
- void (*WriteInquiryTransmitPowerLevel)();
- void (*EnhancedFlush)(uint16_t handle, uint8_t packet_type);
- void (*SendKeypressNotification)(const RawAddress& bd_addr, uint8_t notif);
-
- // STATUS_PARAMETER 0x14xxS
- void (*ReadFailedContactCounter)(uint16_t handle);
- void (*ResetFailedContactCounter)();
- void (*ReadLinkQuality)(uint16_t handle);
- // UNUSED 0x1404
- void (*ReadRssi)(uint16_t handle);
- void (*ReadAfhChannelMap)();
- void (*ReadClock)();
- void (*ReadEncryptionKeySize)();
};
const Interface& GetInterface();
diff --git a/system/stack/include/inq_hci_link_interface.h b/system/stack/include/inq_hci_link_interface.h
index 6ceaae6be2..7d88994520 100644
--- a/system/stack/include/inq_hci_link_interface.h
+++ b/system/stack/include/inq_hci_link_interface.h
@@ -24,13 +24,13 @@
#include "types/raw_address.h"
extern void btm_process_remote_name(const RawAddress* bda, const BD_NAME name,
- uint16_t evt_len, uint8_t hci_status);
+ uint16_t evt_len, tHCI_STATUS hci_status);
extern void btm_process_inq_results(const uint8_t* p, uint8_t hci_evt_len,
uint8_t inq_res_mode);
-extern void btm_process_inq_complete(uint8_t status, uint8_t mode);
-extern void btm_process_cancel_complete(uint8_t status, uint8_t mode);
+extern void btm_process_inq_complete(tHCI_STATUS status, uint8_t mode);
+extern void btm_process_cancel_complete(tHCI_STATUS status, uint8_t mode);
extern void btm_acl_process_sca_cmpl_pkt(uint8_t len, uint8_t* data);
extern tINQ_DB_ENT* btm_inq_db_new(const RawAddress& p_bda);
diff --git a/system/stack/l2cap/l2c_api.cc b/system/stack/l2cap/l2c_api.cc
index b0d7d330a9..41adef29d3 100644
--- a/system/stack/l2cap/l2c_api.cc
+++ b/system/stack/l2cap/l2c_api.cc
@@ -32,11 +32,11 @@
#include <cstdint>
#include <string>
-#include "btm_sec.h"
#include "device/include/controller.h" // TODO Remove
#include "main/shim/shim.h"
#include "osi/include/allocator.h"
#include "osi/include/log.h"
+#include "stack/btm/btm_sec.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/l2c_api.h"
#include "stack/l2cap/l2c_int.h"
diff --git a/system/stack/l2cap/l2c_ble.cc b/system/stack/l2cap/l2c_ble.cc
index 113723efc3..3e5eb7a516 100644..100755
--- a/system/stack/l2cap/l2c_ble.cc
+++ b/system/stack/l2cap/l2c_ble.cc
@@ -28,11 +28,8 @@
#include <base/strings/stringprintf.h>
#include "bt_target.h"
-#include "bta_hearing_aid_api.h"
+#include "bta/include/bta_hearing_aid_api.h"
#include "device/include/controller.h"
-#include "l2c_api.h"
-#include "l2c_int.h"
-#include "l2cdefs.h"
#include "main/shim/l2c_api.h"
#include "main/shim/shim.h"
#include "osi/include/allocator.h"
@@ -41,6 +38,9 @@
#include "stack/btm/btm_dev.h"
#include "stack/btm/btm_sec.h"
#include "stack/include/acl_api.h"
+#include "stack/include/l2c_api.h"
+#include "stack/include/l2cdefs.h"
+#include "stack/l2cap/l2c_int.h"
#include "stack_config.h"
#include "types/raw_address.h"
@@ -671,7 +671,7 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
con_info.l2cap_result = L2CAP_LE_RESULT_INVALID_PARAMETERS;
l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CREDIT_BASED_CONNECT_RSP_NEG,
&con_info);
- break;
+ return;
}
/* At least some of the channels has been created and parameters are
@@ -698,8 +698,27 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
for (int i = 0; i < p_lcb->pending_ecoc_conn_cnt; i++) {
uint16_t cid = p_lcb->pending_ecoc_connection_cids[i];
+ STREAM_TO_UINT16(rcid, p);
+ /* if duplicated remote cid then disconnect original channel
+ * and current channel by sending event to upper layer */
+ temp_p_ccb = l2cu_find_ccb_by_remote_cid(p_lcb, rcid);
+ if (temp_p_ccb != nullptr) {
+ L2CAP_TRACE_ERROR(
+ "Already Allocated Destination cid. "
+ "rcid = %d "
+ "send peer_disc_req", rcid);
+
+ l2cu_send_peer_disc_req(temp_p_ccb);
+
+ temp_p_ccb = l2cu_find_ccb_by_cid(p_lcb, cid);
+ con_info.l2cap_result = L2CAP_LE_RESULT_UNACCEPTABLE_PARAMETERS;
+ l2c_csm_execute(temp_p_ccb, L2CEVT_L2CAP_CREDIT_BASED_CONNECT_RSP_NEG,
+ &con_info);
+ continue;
+ }
+
temp_p_ccb = l2cu_find_ccb_by_cid(p_lcb, cid);
- STREAM_TO_UINT16(temp_p_ccb->remote_cid, p);
+ temp_p_ccb->remote_cid = rcid;
L2CAP_TRACE_DEBUG(
"local cid = %d "
@@ -779,7 +798,7 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
return;
}
- if (p_ccb->peer_conn_cfg.mps > mps) {
+ if (p_ccb->peer_conn_cfg.mps > mps && num_of_channels > 1) {
L2CAP_TRACE_WARNING(
"L2CAP - rcvd config req mps reduction new mps < mps (%d < %d)",
mtu, p_ccb->peer_conn_cfg.mtu);
@@ -812,6 +831,11 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
case L2CAP_CMD_CREDIT_BASED_RECONFIG_RES: {
uint16_t result;
+ if (p + sizeof(uint16_t) > p_pkt_end) {
+ android_errorWriteLog(0x534e4554, "212694559");
+ LOG(ERROR) << "invalid read";
+ return;
+ }
STREAM_TO_UINT16(result, p);
L2CAP_TRACE_DEBUG(
@@ -1022,7 +1046,7 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
l2c_csm_execute(p_ccb, L2CEVT_L2CAP_DISCONNECT_REQ, NULL);
}
} else
- l2cu_send_peer_disc_rsp(p_lcb, id, lcid, rcid);
+ l2cu_send_peer_cmd_reject(p_lcb, L2CAP_CMD_REJ_INVALID_CID, id, 0, 0);
break;
diff --git a/system/stack/l2cap/l2c_csm.cc b/system/stack/l2cap/l2c_csm.cc
index cd1cb3adf3..229c5042a0 100644..100755
--- a/system/stack/l2cap/l2c_csm.cc
+++ b/system/stack/l2cap/l2c_csm.cc
@@ -30,14 +30,14 @@
#include "bt_target.h"
#include "common/time_util.h"
-#include "l2c_int.h"
-#include "l2cdefs.h"
#include "main/shim/metrics_api.h"
#include "osi/include/allocator.h"
#include "osi/include/log.h"
#include "stack/btm/btm_sec.h"
#include "stack/include/acl_api.h"
#include "stack/include/bt_hdr.h"
+#include "stack/include/l2cdefs.h"
+#include "stack/l2cap/l2c_int.h"
/******************************************************************************/
/* L O C A L F U N C T I O N P R O T O T Y P E S */
@@ -823,12 +823,22 @@ static void l2c_csm_w4_l2ca_connect_rsp(tL2C_CCB* p_ccb, tL2CEVT event,
for (int i = 0; i < p_ccb->p_lcb->pending_ecoc_conn_cnt; i++) {
uint16_t cid = p_ccb->p_lcb->pending_ecoc_connection_cids[i];
+ if (cid == 0) {
+ LOG_WARN("pending_ecoc_connection_cids[%d] is %d", i, cid);
+ continue;
+ }
+
tL2C_CCB* temp_p_ccb = l2cu_find_ccb_by_cid(p_ccb->p_lcb, cid);
- auto it = std::find(p_ci->lcids.begin(), p_ci->lcids.end(), cid);
- if (it != p_ci->lcids.end()) {
- temp_p_ccb->chnl_state = CST_OPEN;
- } else {
- l2cu_release_ccb(temp_p_ccb);
+ if (temp_p_ccb) {
+ auto it = std::find(p_ci->lcids.begin(), p_ci->lcids.end(), cid);
+ if (it != p_ci->lcids.end()) {
+ temp_p_ccb->chnl_state = CST_OPEN;
+ } else {
+ l2cu_release_ccb(temp_p_ccb);
+ }
+ }
+ else {
+ LOG_WARN("temp_p_ccb is NULL, pending_ecoc_connection_cids[%d] is %d", i, cid);
}
}
p_ccb->p_lcb->pending_ecoc_conn_cnt = 0;
@@ -871,21 +881,22 @@ static void l2c_csm_w4_l2ca_connect_rsp(tL2C_CCB* p_ccb, tL2CEVT event,
case L2CEVT_L2CA_CREDIT_BASED_CONNECT_RSP_NEG:
p_ci = (tL2C_CONN_INFO*)p_data;
- if (p_ccb->p_lcb && p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
- l2cu_send_peer_credit_based_conn_res(p_ccb, p_ci->lcids,
- p_ci->l2cap_result);
- }
alarm_cancel(p_ccb->l2c_ccb_timer);
- for (int i = 0; i < p_ccb->p_lcb->pending_ecoc_conn_cnt; i++) {
- uint16_t cid = p_ccb->p_lcb->pending_ecoc_connection_cids[i];
- tL2C_CCB* temp_p_ccb = l2cu_find_ccb_by_cid(p_ccb->p_lcb, cid);
- l2cu_release_ccb(temp_p_ccb);
- }
-
- p_ccb->p_lcb->pending_ecoc_conn_cnt = 0;
- memset(p_ccb->p_lcb->pending_ecoc_connection_cids, 0,
- L2CAP_CREDIT_BASED_MAX_CIDS);
+ if (p_ccb->p_lcb != nullptr) {
+ if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
+ l2cu_send_peer_credit_based_conn_res(p_ccb, p_ci->lcids,
+ p_ci->l2cap_result);
+ }
+ for (int i = 0; i < p_ccb->p_lcb->pending_ecoc_conn_cnt; i++) {
+ uint16_t cid = p_ccb->p_lcb->pending_ecoc_connection_cids[i];
+ tL2C_CCB* temp_p_ccb = l2cu_find_ccb_by_cid(p_ccb->p_lcb, cid);
+ l2cu_release_ccb(temp_p_ccb);
+ }
+ p_ccb->p_lcb->pending_ecoc_conn_cnt = 0;
+ memset(p_ccb->p_lcb->pending_ecoc_connection_cids, 0,
+ L2CAP_CREDIT_BASED_MAX_CIDS);
+ }
break;
case L2CEVT_L2CA_CONNECT_RSP_NEG:
p_ci = (tL2C_CONN_INFO*)p_data;
diff --git a/system/stack/l2cap/l2c_fcr.cc b/system/stack/l2cap/l2c_fcr.cc
index 6c17e502d3..1688e9b79a 100644
--- a/system/stack/l2cap/l2c_fcr.cc
+++ b/system/stack/l2cap/l2c_fcr.cc
@@ -29,13 +29,13 @@
#include <string.h>
#include "common/time_util.h"
-#include "l2c_api.h"
-#include "l2c_int.h"
-#include "l2cdefs.h"
#include "osi/include/allocator.h"
#include "osi/include/log.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/bt_types.h"
+#include "stack/include/l2c_api.h"
+#include "stack/include/l2cdefs.h"
+#include "stack/l2cap/l2c_int.h"
/* Flag passed to retransmit_i_frames() when all packets should be retransmitted
*/
diff --git a/system/stack/l2cap/l2c_main.cc b/system/stack/l2cap/l2c_main.cc
index b9bd0c148d..98b00cdfdf 100644
--- a/system/stack/l2cap/l2c_main.cc
+++ b/system/stack/l2cap/l2c_main.cc
@@ -27,15 +27,15 @@
#include <string.h>
#include "bt_target.h"
-#include "hcimsgs.h"
-#include "l2c_api.h"
-#include "l2c_int.h"
-#include "l2cdefs.h"
+#include "hcimsgs.h" // HCID_GET_
#include "main/shim/shim.h"
#include "osi/include/allocator.h"
#include "osi/include/log.h"
#include "osi/include/osi.h"
#include "stack/include/bt_hdr.h"
+#include "stack/include/l2c_api.h"
+#include "stack/include/l2cdefs.h"
+#include "stack/l2cap/l2c_int.h"
/******************************************************************************/
/* L O C A L F U N C T I O N P R O T O T Y P E S */
diff --git a/system/stack/l2cap/l2c_utils.cc b/system/stack/l2cap/l2c_utils.cc
index ebb7a6d018..647e3ae9ea 100644..100755
--- a/system/stack/l2cap/l2c_utils.cc
+++ b/system/stack/l2cap/l2c_utils.cc
@@ -23,13 +23,11 @@
******************************************************************************/
#define LOG_TAG "l2c_utils"
+#include <base/logging.h>
#include <stdio.h>
#include <string.h>
-#include "btm_api.h"
#include "device/include/controller.h"
-#include "l2c_int.h"
-#include "l2cdefs.h"
#include "main/shim/l2c_api.h"
#include "main/shim/shim.h"
#include "osi/include/allocator.h"
@@ -37,11 +35,12 @@
#include "stack/btm/btm_sec.h"
#include "stack/include/acl_api.h"
#include "stack/include/bt_hdr.h"
+#include "stack/include/btm_api.h"
#include "stack/include/hci_error_code.h"
+#include "stack/include/l2cdefs.h"
+#include "stack/l2cap/l2c_int.h"
#include "types/raw_address.h"
-#include <base/logging.h>
-
tL2C_CCB* l2cu_get_next_channel_in_rr(tL2C_LCB* p_lcb); // TODO Move
/*******************************************************************************
@@ -2948,7 +2947,7 @@ void l2cu_reject_ble_connection(tL2C_CCB* p_ccb, uint8_t rem_id,
uint16_t result) {
if (p_ccb->ecoc)
l2cu_reject_credit_based_conn_req(
- p_ccb->p_lcb, rem_id, p_ccb->p_lcb->pending_ecoc_reconfig_cnt, result);
+ p_ccb->p_lcb, rem_id, p_ccb->p_lcb->pending_ecoc_conn_cnt, result);
else
l2cu_reject_ble_coc_connection(p_ccb->p_lcb, rem_id, result);
}
diff --git a/system/stack/test/ble_advertiser_test.cc b/system/stack/test/ble_advertiser_test.cc
index b4a8b851b0..35855168f8 100644
--- a/system/stack/test/ble_advertiser_test.cc
+++ b/system/stack/test/ble_advertiser_test.cc
@@ -89,6 +89,9 @@ constexpr uint8_t COMPLETE = 0x03; // Complete extended advertising data
class AdvertiserHciMock : public BleAdvertiserHciInterface {
public:
AdvertiserHciMock() = default;
+ AdvertiserHciMock(const AdvertiserHciMock&) = delete;
+ AdvertiserHciMock& operator=(const AdvertiserHciMock&) = delete;
+
~AdvertiserHciMock() override = default;
MOCK_METHOD1(ReadInstanceCount,
@@ -133,9 +136,6 @@ class AdvertiserHciMock : public BleAdvertiserHciInterface {
};
bool QuirkAdvertiserZeroHandle() override { return false; }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(AdvertiserHciMock);
};
} // namespace
diff --git a/system/stack/test/btm_iso_test.cc b/system/stack/test/btm_iso_test.cc
index 94e77fceba..f4984296f7 100644
--- a/system/stack/test/btm_iso_test.cc
+++ b/system/stack/test/btm_iso_test.cc
@@ -69,6 +69,9 @@ namespace {
class MockCigCallbacks : public bluetooth::hci::iso_manager::CigCallbacks {
public:
MockCigCallbacks() = default;
+ MockCigCallbacks(const MockCigCallbacks&) = delete;
+ MockCigCallbacks& operator=(const MockCigCallbacks&) = delete;
+
~MockCigCallbacks() override = default;
MOCK_METHOD((void), OnSetupIsoDataPath,
@@ -86,14 +89,14 @@ class MockCigCallbacks : public bluetooth::hci::iso_manager::CigCallbacks {
MOCK_METHOD((void), OnCisEvent, (uint8_t event, void* data), (override));
MOCK_METHOD((void), OnCigEvent, (uint8_t event, void* data), (override));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockCigCallbacks);
};
class MockBigCallbacks : public bluetooth::hci::iso_manager::BigCallbacks {
public:
MockBigCallbacks() = default;
+ MockBigCallbacks(const MockBigCallbacks&) = delete;
+ MockBigCallbacks& operator=(const MockBigCallbacks&) = delete;
+
~MockBigCallbacks() override = default;
MOCK_METHOD((void), OnSetupIsoDataPath,
@@ -104,9 +107,6 @@ class MockBigCallbacks : public bluetooth::hci::iso_manager::BigCallbacks {
(override));
MOCK_METHOD((void), OnBigEvent, (uint8_t event, void* data), (override));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockBigCallbacks);
};
} // namespace
@@ -1288,7 +1288,8 @@ TEST_F(IsoManagerDeathTest, CreateBigInvalidResponsePacket) {
});
ASSERT_EXIT(IsoManager::GetInstance()->CreateBig(0x01, kDefaultBigParams),
- ::testing::KilledBySignal(SIGABRT), "Invalid bis count");
+ ::testing::KilledBySignal(SIGABRT),
+ "num_bis != 0. Bis count is 0");
}
TEST_F(IsoManagerDeathTest, CreateBigInvalidResponsePacket2) {
@@ -1804,6 +1805,17 @@ TEST_F(IsoManagerTest, RemoveIsoDataPathInvalidStatus) {
iso_handle, kDefaultIsoDataPathParams.data_path_dir);
}
+TEST_F(IsoManagerTest, SendIsoDataWithNoCigConnected) {
+ std::vector<uint8_t> data_vec(108, 0);
+ IsoManager::GetInstance()->CreateCig(
+ volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
+
+ auto handle = volatile_test_cig_create_cmpl_evt_.conn_handles[0];
+ IsoManager::GetInstance()->SendIsoData(handle, data_vec.data(),
+ data_vec.size());
+ EXPECT_CALL(bte_interface_, HciSend).Times(0);
+}
+
TEST_F(IsoManagerTest, SendIsoDataCigValid) {
IsoManager::GetInstance()->CreateCig(
volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
@@ -2136,17 +2148,6 @@ TEST_F(IsoManagerDeathTest, SendIsoDataWithNoCigBigHandle) {
::testing::KilledBySignal(SIGABRT), "No such iso");
}
-TEST_F(IsoManagerDeathTest, SendIsoDataWithNoCigConnected) {
- std::vector<uint8_t> data_vec(108, 0);
- IsoManager::GetInstance()->CreateCig(
- volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
-
- auto handle = volatile_test_cig_create_cmpl_evt_.conn_handles[0];
- ASSERT_EXIT(IsoManager::GetInstance()->SendIsoData(handle, data_vec.data(),
- data_vec.size()),
- ::testing::KilledBySignal(SIGABRT), "CIS not established");
-}
-
TEST_F(IsoManagerTest, HandleDisconnectNoSuchHandle) {
// Don't expect any callbacks when connection handle is not for ISO.
EXPECT_CALL(*cig_callbacks_, OnCigEvent).Times(0);
diff --git a/system/stack/test/common/mock_eatt.h b/system/stack/test/common/mock_eatt.h
index 8b5d9d58ca..a7b6c5f867 100644
--- a/system/stack/test/common/mock_eatt.h
+++ b/system/stack/test/common/mock_eatt.h
@@ -27,6 +27,9 @@ using bluetooth::eatt::EattExtension;
class MockEattExtension : public EattExtension {
public:
MockEattExtension() = default;
+ MockEattExtension(const MockEattExtension&) = delete;
+ MockEattExtension& operator=(const MockEattExtension&) = delete;
+
~MockEattExtension() override = default;
static MockEattExtension* GetInstance();
@@ -65,7 +68,4 @@ class MockEattExtension : public EattExtension {
MOCK_METHOD((void), Start, ());
MOCK_METHOD((void), Stop, ());
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockEattExtension);
};
diff --git a/system/stack/test/fuzzers/Android.bp b/system/stack/test/fuzzers/Android.bp
index 1dd4f61d64..ca3c6a3afc 100644
--- a/system/stack/test/fuzzers/Android.bp
+++ b/system/stack/test/fuzzers/Android.bp
@@ -34,7 +34,6 @@ cc_defaults {
"libbt-hci",
"libbtdevice",
"libg722codec",
- "liblc3codec",
"liblc3",
"libosi",
"libudrv-uipc",
@@ -52,7 +51,6 @@ cc_defaults {
"android.hardware.bluetooth.a2dp@1.0",
"android.hardware.bluetooth.audio@2.0",
"android.hardware.bluetooth.audio@2.1",
- "android.hardware.bluetooth.audio@2.2",
"android.hardware.bluetooth.audio-V1-ndk",
"android.system.suspend.control-V1-ndk",
"libaaudio",
diff --git a/system/test/Android.bp b/system/test/Android.bp
index fa07d7ec9e..7754163ae7 100644
--- a/system/test/Android.bp
+++ b/system/test/Android.bp
@@ -425,6 +425,13 @@ filegroup {
}
filegroup {
+ name: "TestCommonStackConfig",
+ srcs: [
+ "common/stack_config.cc",
+ ],
+}
+
+filegroup {
name: "TestMockBluetoothInterface",
srcs: [
"mock/mock_bluetooth_interface.cc",
diff --git a/system/test/common/stack_config.cc b/system/test/common/stack_config.cc
new file mode 100644
index 0000000000..db34351d73
--- /dev/null
+++ b/system/test/common/stack_config.cc
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2022 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 "internal_include/stack_config.h"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <cstdarg>
+#include <cstring>
+
+const std::string kSmpOptions("mock smp options");
+bool get_trace_config_enabled(void) { return false; }
+bool get_pts_avrcp_test(void) { return false; }
+bool get_pts_secure_only_mode(void) { return false; }
+bool get_pts_conn_updates_disabled(void) { return false; }
+bool get_pts_crosskey_sdp_disable(void) { return false; }
+const std::string* get_pts_smp_options(void) { return &kSmpOptions; }
+int get_pts_smp_failure_case(void) { return 123; }
+struct config_t;
+config_t* get_all(void) { return nullptr; }
+struct packet_fragmenter_t;
+const packet_fragmenter_t* packet_fragmenter_get_interface() { return nullptr; }
+
+stack_config_t mock_stack_config{
+ .get_trace_config_enabled = get_trace_config_enabled,
+ .get_pts_avrcp_test = get_pts_avrcp_test,
+ .get_pts_secure_only_mode = get_pts_secure_only_mode,
+ .get_pts_conn_updates_disabled = get_pts_conn_updates_disabled,
+ .get_pts_crosskey_sdp_disable = get_pts_crosskey_sdp_disable,
+ .get_pts_smp_options = get_pts_smp_options,
+ .get_pts_smp_failure_case = get_pts_smp_failure_case,
+ .get_all = get_all,
+};
+
+const stack_config_t* stack_config_get_interface(void) {
+ return &mock_stack_config;
+}
diff --git a/system/test/headless/Android.bp b/system/test/headless/Android.bp
index b05e31c3c4..b0f6c343e2 100644
--- a/system/test/headless/Android.bp
+++ b/system/test/headless/Android.bp
@@ -49,7 +49,6 @@ cc_test {
"libbtif",
"libflatbuffers-cpp",
"libg722codec",
- "liblc3codec",
"liblc3",
"libosi",
"libprotobuf-cpp-lite",
@@ -61,7 +60,6 @@ cc_test {
"android.hardware.bluetooth.a2dp@1.0",
"android.hardware.bluetooth.audio@2.0",
"android.hardware.bluetooth.audio@2.1",
- "android.hardware.bluetooth.audio@2.2",
"android.hardware.bluetooth.audio-V1-ndk",
"android.hardware.bluetooth@1.0",
"android.hardware.bluetooth@1.1",
diff --git a/system/test/headless/headless.cc b/system/test/headless/headless.cc
index d9b12fd2f7..498ae1a067 100644
--- a/system/test/headless/headless.cc
+++ b/system/test/headless/headless.cc
@@ -137,8 +137,7 @@ void link_quality_report(uint64_t timestamp, int report_id, int rssi, int snr,
}
/** Switch buffer size callback */
-void switch_buffer_size(RawAddress* remote_addr,
- bool is_low_latency_buffer_size) {
+void switch_buffer_size(bool is_low_latency_buffer_size) {
LOG_INFO("%s", __func__);
}
diff --git a/system/test/mock/mock_bluetooth_interface.cc b/system/test/mock/mock_bluetooth_interface.cc
index 8f1423e77a..4312828ff5 100644
--- a/system/test/mock/mock_bluetooth_interface.cc
+++ b/system/test/mock/mock_bluetooth_interface.cc
@@ -149,6 +149,8 @@ static bool allow_low_latency_audio(bool allowed, const RawAddress& address) {
return true;
}
+static int clear_event_filter(void) { return 0; }
+
EXPORT_SYMBOL bt_interface_t bluetoothInterface = {
sizeof(bluetoothInterface),
init,
@@ -188,7 +190,8 @@ EXPORT_SYMBOL bt_interface_t bluetoothInterface = {
get_metric_id,
set_dynamic_audio_buffer_size,
generate_local_oob_data,
- allow_low_latency_audio};
+ allow_low_latency_audio,
+ clear_event_filter};
// callback reporting helpers
diff --git a/system/test/mock/mock_bta_dm_act.h b/system/test/mock/mock_bta_dm_act.h
index 2c99aa172d..5a566dcb7d 100644
--- a/system/test/mock/mock_bta_dm_act.h
+++ b/system/test/mock/mock_bta_dm_act.h
@@ -255,6 +255,15 @@ struct bta_dm_ble_observe {
};
extern struct bta_dm_ble_observe bta_dm_ble_observe;
+// Name: bta_dm_clear_event_filter
+// Params: None
+// Return: void
+struct bta_dm_clear_event_filter {
+ std::function<void()> body{[]() {}};
+ void operator()() { body(); };
+};
+extern struct bta_dm_clear_event_filter bta_dm_clear_event_filter;
+
// Name: bta_dm_ble_passkey_reply
// Params: const RawAddress& bd_addr, bool accept, uint32_t passkey
// Return: void
diff --git a/system/test/mock/mock_bta_leaudio.cc b/system/test/mock/mock_bta_leaudio.cc
index 1af8dbf369..ecb0114721 100644
--- a/system/test/mock/mock_bta_leaudio.cc
+++ b/system/test/mock/mock_bta_leaudio.cc
@@ -52,7 +52,10 @@ void LeAudioClient::AddFromStorage(const RawAddress& address,
bool auto_connect) {
mock_function_count_map[__func__]++;
}
-void LeAudioClient::Cleanup() { mock_function_count_map[__func__]++; }
+void LeAudioClient::Cleanup(base::Callback<void()> cleanupCb) {
+ std::move(cleanupCb).Run();
+ mock_function_count_map[__func__]++;
+}
LeAudioClient* LeAudioClient::Get(void) {
mock_function_count_map[__func__]++;
@@ -64,7 +67,15 @@ bool LeAudioClient::IsLeAudioClientRunning(void) {
}
void LeAudioClient::Initialize(
bluetooth::le_audio::LeAudioClientCallbacks* callbacks_,
- base::Closure initCb, base::Callback<bool()> hal_2_1_verifier) {
+ base::Closure initCb, base::Callback<bool()> hal_2_1_verifier,
+ const std::vector<bluetooth::le_audio::btle_audio_codec_config_t>&
+ offloading_preference) {
+ mock_function_count_map[__func__]++;
+}
+void LeAudioClient::DebugDump(int fd) { mock_function_count_map[__func__]++; }
+void LeAudioClient::InitializeAudioSetConfigurationProvider() {
+ mock_function_count_map[__func__]++;
+}
+void LeAudioClient::CleanupAudioSetConfigurationProvider() {
mock_function_count_map[__func__]++;
}
-void LeAudioClient::DebugDump(int fd) { mock_function_count_map[__func__]++; } \ No newline at end of file
diff --git a/system/test/mock/mock_device_controller.cc b/system/test/mock/mock_device_controller.cc
index bb89e7d0f9..32c7710f74 100644
--- a/system/test/mock/mock_device_controller.cc
+++ b/system/test/mock/mock_device_controller.cc
@@ -367,6 +367,8 @@ uint8_t get_le_all_initiating_phys() {
return phy;
}
+tBTM_STATUS clear_event_filter() { return BTM_SUCCESS; }
+
const controller_t interface = {
get_is_ready,
@@ -451,7 +453,8 @@ const controller_t interface = {
get_ble_resolving_list_max_size,
set_ble_resolving_list_max_size,
get_local_supported_codecs,
- get_le_all_initiating_phys};
+ get_le_all_initiating_phys,
+ clear_event_filter};
} // namespace device_controller
} // namespace mock
diff --git a/system/test/mock/mock_le_audio_hal_verifier.cc b/system/test/mock/mock_le_audio_hal_verifier.cc
index 9c378edf24..8d729236c6 100644
--- a/system/test/mock/mock_le_audio_hal_verifier.cc
+++ b/system/test/mock/mock_le_audio_hal_verifier.cc
@@ -29,3 +29,8 @@ bool LeAudioHalVerifier::SupportsLeAudioHardwareOffload() {
mock_function_count_map[__func__]++;
return true;
}
+
+bool LeAudioHalVerifier::SupportsLeAudioBroadcast() {
+ mock_function_count_map[__func__]++;
+ return true;
+}
diff --git a/system/test/mock/mock_main_shim_btm_api.cc b/system/test/mock/mock_main_shim_btm_api.cc
index f0223d2b60..a2a13194c4 100644
--- a/system/test/mock/mock_main_shim_btm_api.cc
+++ b/system/test/mock/mock_main_shim_btm_api.cc
@@ -432,3 +432,8 @@ void btm_api_process_inquiry_result_with_rssi(RawAddress raw_address,
int8_t rssi) {
mock_function_count_map[__func__]++;
}
+
+tBTM_STATUS bluetooth::shim::BTM_ClearEventFilter() {
+ mock_function_count_map[__func__]++;
+ return BTM_SUCCESS;
+}
diff --git a/system/test/mock/mock_main_shim_metrics_api.cc b/system/test/mock/mock_main_shim_metrics_api.cc
index 1b638395b0..25b32283fc 100644
--- a/system/test/mock/mock_main_shim_metrics_api.cc
+++ b/system/test/mock/mock_main_shim_metrics_api.cc
@@ -174,5 +174,9 @@ void bluetooth::shim::LogMetricManufacturerInfo(
raw_address, source_type, source_name, manufacturer, model,
hardware_version, software_version);
}
+bool bluetooth::shim::CountCounterMetrics(int32_t key, int64_t count) {
+ mock_function_count_map[__func__]++;
+ return false;
+}
// END mockcify generation
diff --git a/system/test/mock/mock_stack_acl_btm_ble_connection_establishment.cc b/system/test/mock/mock_stack_acl_btm_ble_connection_establishment.cc
index 061920d710..d9ded82226 100644
--- a/system/test/mock/mock_stack_acl_btm_ble_connection_establishment.cc
+++ b/system/test/mock/mock_stack_acl_btm_ble_connection_establishment.cc
@@ -50,7 +50,6 @@ namespace mock {
namespace stack_acl_btm_ble_connection_establishment {
// Function state capture and return values, if needed
-struct btm_send_hci_create_connection btm_send_hci_create_connection;
struct btm_ble_create_ll_conn_complete btm_ble_create_ll_conn_complete;
struct maybe_resolve_address maybe_resolve_address;
struct btm_ble_conn_complete btm_ble_conn_complete;
@@ -61,20 +60,6 @@ struct btm_ble_create_conn_cancel_complete btm_ble_create_conn_cancel_complete;
} // namespace mock
} // namespace test
-// Mocked functions, if any
-void btm_send_hci_create_connection(
- uint16_t scan_int, uint16_t scan_win, uint8_t init_filter_policy,
- uint8_t addr_type_peer, const RawAddress& bda_peer, uint8_t addr_type_own,
- uint16_t conn_int_min, uint16_t conn_int_max, uint16_t conn_latency,
- uint16_t conn_timeout, uint16_t min_ce_len, uint16_t max_ce_len,
- uint8_t initiating_phys) {
- mock_function_count_map[__func__]++;
- test::mock::stack_acl_btm_ble_connection_establishment::
- btm_send_hci_create_connection(
- scan_int, scan_win, init_filter_policy, addr_type_peer, bda_peer,
- addr_type_own, conn_int_min, conn_int_max, conn_latency, conn_timeout,
- min_ce_len, max_ce_len, initiating_phys);
-}
void btm_ble_create_ll_conn_complete(tHCI_STATUS status) {
mock_function_count_map[__func__]++;
test::mock::stack_acl_btm_ble_connection_establishment::
diff --git a/system/test/mock/mock_stack_acl_btm_ble_connection_establishment.h b/system/test/mock/mock_stack_acl_btm_ble_connection_establishment.h
index c546d030e6..d988d946aa 100644
--- a/system/test/mock/mock_stack_acl_btm_ble_connection_establishment.h
+++ b/system/test/mock/mock_stack_acl_btm_ble_connection_establishment.h
@@ -48,38 +48,6 @@ namespace mock {
namespace stack_acl_btm_ble_connection_establishment {
// Shared state between mocked functions and tests
-// Name: btm_send_hci_create_connection
-// Params: uint16_t scan_int, uint16_t scan_win, uint8_t init_filter_policy,
-// uint8_t addr_type_peer, const RawAddress& bda_peer, uint8_t addr_type_own,
-// uint16_t conn_int_min, uint16_t conn_int_max, uint16_t conn_latency, uint16_t
-// conn_timeout, uint16_t min_ce_len, uint16_t max_ce_len, uint8_t
-// initiating_phys Returns: void
-struct btm_send_hci_create_connection {
- std::function<void(
- uint16_t scan_int, uint16_t scan_win, uint8_t init_filter_policy,
- uint8_t addr_type_peer, const RawAddress& bda_peer, uint8_t addr_type_own,
- uint16_t conn_int_min, uint16_t conn_int_max, uint16_t conn_latency,
- uint16_t conn_timeout, uint16_t min_ce_len, uint16_t max_ce_len,
- uint8_t initiating_phys)>
- body{[](uint16_t scan_int, uint16_t scan_win, uint8_t init_filter_policy,
- uint8_t addr_type_peer, const RawAddress& bda_peer,
- uint8_t addr_type_own, uint16_t conn_int_min,
- uint16_t conn_int_max, uint16_t conn_latency,
- uint16_t conn_timeout, uint16_t min_ce_len, uint16_t max_ce_len,
- uint8_t initiating_phys) {}};
- void operator()(uint16_t scan_int, uint16_t scan_win,
- uint8_t init_filter_policy, uint8_t addr_type_peer,
- const RawAddress& bda_peer, uint8_t addr_type_own,
- uint16_t conn_int_min, uint16_t conn_int_max,
- uint16_t conn_latency, uint16_t conn_timeout,
- uint16_t min_ce_len, uint16_t max_ce_len,
- uint8_t initiating_phys) {
- body(scan_int, scan_win, init_filter_policy, addr_type_peer, bda_peer,
- addr_type_own, conn_int_min, conn_int_max, conn_latency, conn_timeout,
- min_ce_len, max_ce_len, initiating_phys);
- };
-};
-extern struct btm_send_hci_create_connection btm_send_hci_create_connection;
// Name: btm_ble_create_ll_conn_complete
// Params: tHCI_STATUS status
// Returns: void
diff --git a/system/test/mock/mock_stack_btm_ble.cc b/system/test/mock/mock_stack_btm_ble.cc
index da844aa876..5ebd1a5f57 100644
--- a/system/test/mock/mock_stack_btm_ble.cc
+++ b/system/test/mock/mock_stack_btm_ble.cc
@@ -230,9 +230,6 @@ void btm_ble_rand_enc_complete(uint8_t* p, uint16_t op_code,
tBTM_RAND_ENC_CB* p_enc_cplt_cback) {
mock_function_count_map[__func__]++;
}
-void btm_ble_set_random_address(const RawAddress& random_bda) {
- mock_function_count_map[__func__]++;
-}
void btm_ble_test_command_complete(uint8_t* p) {
mock_function_count_map[__func__]++;
}
diff --git a/system/test/mock/mock_stack_btm_inq.cc b/system/test/mock/mock_stack_btm_inq.cc
index f938adbe7c..1d1c8e25ee 100644
--- a/system/test/mock/mock_stack_btm_inq.cc
+++ b/system/test/mock/mock_stack_btm_inq.cc
@@ -166,10 +166,10 @@ void btm_inq_rmt_name_failed_cancelled(void) {
mock_function_count_map[__func__]++;
}
void btm_inq_stop_on_ssp(void) { mock_function_count_map[__func__]++; }
-void btm_process_cancel_complete(uint8_t status, uint8_t mode) {
+void btm_process_cancel_complete(tHCI_STATUS status, uint8_t mode) {
mock_function_count_map[__func__]++;
}
-void btm_process_inq_complete(uint8_t status, uint8_t mode) {
+void btm_process_inq_complete(tHCI_STATUS status, uint8_t mode) {
mock_function_count_map[__func__]++;
}
void btm_process_inq_results(const uint8_t* p, uint8_t hci_evt_len,
@@ -177,7 +177,7 @@ void btm_process_inq_results(const uint8_t* p, uint8_t hci_evt_len,
mock_function_count_map[__func__]++;
}
void btm_process_remote_name(const RawAddress* bda, const BD_NAME bdn,
- uint16_t evt_len, uint8_t hci_status) {
+ uint16_t evt_len, tHCI_STATUS hci_status) {
mock_function_count_map[__func__]++;
}
void btm_set_eir_uuid(const uint8_t* p_eir, tBTM_INQ_RESULTS* p_results) {
diff --git a/system/test/rootcanal/Android.bp b/system/test/rootcanal/Android.bp
index 2887239f41..5d6700f273 100644
--- a/system/test/rootcanal/Android.bp
+++ b/system/test/rootcanal/Android.bp
@@ -61,7 +61,6 @@ cc_binary {
"android.hardware.bluetooth-async",
"android.hardware.bluetooth-hci",
"libbt-rootcanal",
- "libbt-rootcanal-types",
"libscriptedbeaconpayload-protos-lite",
],
include_dirs: [
@@ -111,7 +110,6 @@ cc_library_shared {
"android.hardware.bluetooth-async",
"android.hardware.bluetooth-hci",
"libbt-rootcanal",
- "libbt-rootcanal-types",
"libscriptedbeaconpayload-protos-lite",
],
include_dirs: [
diff --git a/system/test/stub/osi.cc b/system/test/stub/osi.cc
index e07adcba52..f5b5602ca3 100644
--- a/system/test/stub/osi.cc
+++ b/system/test/stub/osi.cc
@@ -380,15 +380,21 @@ alarm_t* alarm_new_periodic(const char* name) {
mock_function_count_map[__func__]++;
return nullptr;
}
+struct fake_osi_alarm_set_on_mloop fake_osi_alarm_set_on_mloop_;
bool alarm_is_scheduled(const alarm_t* alarm) {
mock_function_count_map[__func__]++;
- return false;
+ return (fake_osi_alarm_set_on_mloop_.cb != nullptr);
}
uint64_t alarm_get_remaining_ms(const alarm_t* alarm) {
mock_function_count_map[__func__]++;
return 0;
}
-void alarm_cancel(alarm_t* alarm) { mock_function_count_map[__func__]++; }
+void alarm_cancel(alarm_t* alarm) {
+ mock_function_count_map[__func__]++;
+ fake_osi_alarm_set_on_mloop_.interval_ms = 0;
+ fake_osi_alarm_set_on_mloop_.cb = nullptr;
+ fake_osi_alarm_set_on_mloop_.data = nullptr;
+}
void alarm_cleanup(void) { mock_function_count_map[__func__]++; }
void alarm_debug_dump(int fd) { mock_function_count_map[__func__]++; }
void alarm_free(alarm_t* alarm) { mock_function_count_map[__func__]++; }
@@ -397,7 +403,6 @@ void alarm_set(alarm_t* alarm, uint64_t interval_ms, alarm_callback_t cb,
mock_function_count_map[__func__]++;
}
-struct fake_osi_alarm_set_on_mloop fake_osi_alarm_set_on_mloop_;
void alarm_set_on_mloop(alarm_t* alarm, uint64_t interval_ms,
alarm_callback_t cb, void* data) {
mock_function_count_map[__func__]++;
diff --git a/system/test/suite/adapter/bluetooth_test.h b/system/test/suite/adapter/bluetooth_test.h
index 44f52c80da..6b50be9f95 100644
--- a/system/test/suite/adapter/bluetooth_test.h
+++ b/system/test/suite/adapter/bluetooth_test.h
@@ -41,6 +41,9 @@ class BluetoothTest : public ::testing::Test,
public bluetooth::hal::BluetoothInterface::Observer {
protected:
BluetoothTest() = default;
+ BluetoothTest(const BluetoothTest&) = delete;
+ BluetoothTest& operator=(const BluetoothTest&) = delete;
+
virtual ~BluetoothTest() = default;
// Getter for the bt_interface
@@ -115,8 +118,6 @@ class BluetoothTest : public ::testing::Test,
bt_discovery_state_t discovery_state_;
bt_acl_state_t acl_state_;
bt_bond_state_t bond_state_;
-
- DISALLOW_COPY_AND_ASSIGN(BluetoothTest);
};
} // bttest
diff --git a/system/test/suite/gatt/gatt_test.h b/system/test/suite/gatt/gatt_test.h
index 1fcea738bd..da0d6d218c 100644
--- a/system/test/suite/gatt/gatt_test.h
+++ b/system/test/suite/gatt/gatt_test.h
@@ -31,6 +31,9 @@ class GattTest : public BluetoothTest,
public bluetooth::hal::BluetoothGattInterface::ServerObserver {
protected:
GattTest() = default;
+ GattTest(const GattTest&) = delete;
+ GattTest& operator=(const GattTest&) = delete;
+
virtual ~GattTest() = default;
// Gets the gatt_scanner_interface
@@ -125,8 +128,6 @@ class GattTest : public BluetoothTest,
// The status of the last callback. Is BT_STATUS_SUCCESS if no issues.
int status_;
-
- DISALLOW_COPY_AND_ASSIGN(GattTest);
};
} // bttest
diff --git a/system/tools/bdtool/adapter.c b/system/tools/bdtool/adapter.c
index bfbbfeb904..3b964a0f78 100644
--- a/system/tools/bdtool/adapter.c
+++ b/system/tools/bdtool/adapter.c
@@ -257,7 +257,7 @@ static void parse_properties(int num_properties, bt_property_t* property) {
case BT_PROPERTY_SERVICE_RECORD:
case BT_PROPERTY_ADAPTER_SCAN_MODE:
case BT_PROPERTY_ADAPTER_BONDED_DEVICES:
- case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
+ case BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT:
case BT_PROPERTY_REMOTE_VERSION_INFO:
case BT_PROPERTY_LOCAL_LE_FEATURES:
case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP:
diff --git a/system/vendor_libs/test_vendor_lib/Android.bp b/system/vendor_libs/test_vendor_lib/Android.bp
index 177a37f990..1c69551e1e 100644
--- a/system/vendor_libs/test_vendor_lib/Android.bp
+++ b/system/vendor_libs/test_vendor_lib/Android.bp
@@ -84,7 +84,6 @@ cc_library_static {
],
static_libs: [
"libjsoncpp",
- "libbt-rootcanal-types",
"libscriptedbeaconpayload-protos-lite",
],
}
@@ -127,7 +126,6 @@ cc_test_host {
"liblog",
],
static_libs: [
- "libbt-rootcanal-types",
"libbt-rootcanal",
],
cflags: [
@@ -174,7 +172,6 @@ cc_binary_host {
],
static_libs: [
"libjsoncpp",
- "libbt-rootcanal-types",
"libprotobuf-cpp-lite",
"libscriptedbeaconpayload-protos-lite",
"libbt-rootcanal",
diff --git a/system/vendor_libs/test_vendor_lib/include/inquiry.h b/system/vendor_libs/test_vendor_lib/include/inquiry.h
deleted file mode 100644
index f989af4bea..0000000000
--- a/system/vendor_libs/test_vendor_lib/include/inquiry.h
+++ /dev/null
@@ -1,33 +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
-
-namespace test_vendor_lib {
-
-class Inquiry {
- public:
- enum class InquiryState : uint8_t {
- STANDBY = 0x00,
- INQUIRY = 0x01,
- };
- enum class InquiryType : uint8_t {
- STANDARD = 0x00,
- RSSI = 0x01,
- EXTENDED = 0x02,
- };
-};
-} // namespace test_vendor_lib
diff --git a/system/vendor_libs/test_vendor_lib/include/le_advertisement.h b/system/vendor_libs/test_vendor_lib/include/le_advertisement.h
deleted file mode 100644
index a5c139630e..0000000000
--- a/system/vendor_libs/test_vendor_lib/include/le_advertisement.h
+++ /dev/null
@@ -1,40 +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 <cstdint>
-
-namespace test_vendor_lib {
-
-class LeAdvertisement {
- public:
- enum class AdvertisementType : uint8_t {
- ADV_IND = 0, // Connectable and scannable
- ADV_DIRECT_IND = 1, // Connectable directed
- ADV_SCAN_IND = 2, // Scannable undirected
- ADV_NONCONN_IND = 3, // Non connectable undirected
- SCAN_RESPONSE = 4,
- };
- enum class AddressType : uint8_t {
- PUBLIC = 0,
- RANDOM = 1,
- PUBLIC_IDENTITY = 2,
- RANDOM_IDENTITY = 3,
- };
-};
-
-} // namespace test_vendor_lib
diff --git a/system/vendor_libs/test_vendor_lib/include/sco.h b/system/vendor_libs/test_vendor_lib/include/sco.h
deleted file mode 100644
index b3691cf10f..0000000000
--- a/system/vendor_libs/test_vendor_lib/include/sco.h
+++ /dev/null
@@ -1,33 +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 <cstdint>
-
-namespace test_vendor_lib {
-namespace sco {
-
-// SCO data packets are specified in the Bluetooth Core Specification Version
-// 4.2, Volume 2, Part E, Section 5.4.3
-enum class PacketStatusFlagsType : uint8_t {
- CORRECTLY_RECEIVED = 0,
- POSSIBLY_INCOMPLETE = 1,
- NO_DATA = 2,
- PARTIALLY_LOST = 3
-};
-} // namespace sco
-} // namespace test_vendor_lib
diff --git a/system/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.cc b/system/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.cc
index ce68d3f7da..8d4f08ff8a 100644
--- a/system/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.cc
+++ b/system/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.cc
@@ -19,6 +19,7 @@
#include <memory>
#include <random>
+#include "crypto_toolbox/crypto_toolbox.h"
#include "os/log.h"
#include "packet/raw_builder.h"
@@ -231,6 +232,7 @@ DualModeController::DualModeController(const std::string& properties_filename, u
SET_SUPPORTED(LE_ADD_DEVICE_TO_CONNECT_LIST, LeAddDeviceToConnectList);
SET_SUPPORTED(LE_REMOVE_DEVICE_FROM_CONNECT_LIST,
LeRemoveDeviceFromConnectList);
+ SET_SUPPORTED(LE_ENCRYPT, LeEncrypt);
SET_SUPPORTED(LE_RAND, LeRand);
SET_SUPPORTED(LE_READ_SUPPORTED_STATES, LeReadSupportedStates);
SET_HANDLER(LE_GET_VENDOR_CAPABILITIES, LeVendorCap);
@@ -2289,6 +2291,18 @@ void DualModeController::LeReadRemoteFeatures(CommandView command) {
status, kNumCommandPackets));
}
+void DualModeController::LeEncrypt(CommandView command) {
+ auto command_view = gd_hci::LeEncryptView::Create(
+ gd_hci::LeSecurityCommandView::Create(command));
+ ASSERT(command_view.IsValid());
+
+ auto encrypted_data = bluetooth::crypto_toolbox::aes_128(
+ command_view.GetKey(),
+ command_view.GetPlaintextData());
+
+ send_event_(bluetooth::hci::LeEncryptCompleteBuilder::Create(
+ kNumCommandPackets, ErrorCode::SUCCESS, encrypted_data));
+}
static std::random_device rd{};
static std::mt19937_64 s_mt{rd()};
@@ -2416,7 +2430,8 @@ void DualModeController::LeSetExtendedAdvertisingParameters(
command_view.GetPrimaryAdvertisingIntervalMax(),
command_view.GetAdvertisingEventLegacyProperties(),
command_view.GetOwnAddressType(), command_view.GetPeerAddressType(),
- command_view.GetPeerAddress(), command_view.GetAdvertisingFilterPolicy());
+ command_view.GetPeerAddress(), command_view.GetAdvertisingFilterPolicy(),
+ command_view.GetAdvertisingTxPower());
send_event_(
bluetooth::hci::LeSetExtendedAdvertisingParametersCompleteBuilder::Create(
diff --git a/system/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.h b/system/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.h
index 1e88f51b8b..785bc041cc 100644
--- a/system/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.h
+++ b/system/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.h
@@ -471,6 +471,9 @@ class DualModeController : public Device {
// 7.8.21
void LeReadRemoteFeatures(CommandView args);
+ // 7.8.22
+ void LeEncrypt(CommandView args);
+
// 7.8.23
void LeRand(CommandView args);
diff --git a/system/vendor_libs/test_vendor_lib/model/controller/le_advertiser.cc b/system/vendor_libs/test_vendor_lib/model/controller/le_advertiser.cc
index 27a63fe5e8..661d7b76e3 100644
--- a/system/vendor_libs/test_vendor_lib/model/controller/le_advertiser.cc
+++ b/system/vendor_libs/test_vendor_lib/model/controller/le_advertiser.cc
@@ -17,6 +17,7 @@
#include "le_advertiser.h"
using namespace bluetooth::hci;
+using namespace std::literals;
namespace test_vendor_lib {
void LeAdvertiser::Initialize(AddressWithType address,
@@ -33,21 +34,28 @@ void LeAdvertiser::Initialize(AddressWithType address,
advertisement_ = advertisement;
scan_response_ = scan_response;
interval_ = interval;
+ tx_power_ = kTxPowerUnavailable;
}
void LeAdvertiser::InitializeExtended(
- AddressType address_type, AddressWithType peer_address,
+ unsigned advertising_handle,
+ AddressType address_type,
+ AddressWithType peer_address,
LeScanningFilterPolicy filter_policy,
model::packets::AdvertisementType type,
- std::chrono::steady_clock::duration interval) {
+ std::chrono::steady_clock::duration interval,
+ uint8_t tx_power) {
+
+ advertising_handle_ = advertising_handle;
address_ = AddressWithType(address_.GetAddress(), address_type);
peer_address_ = peer_address;
filter_policy_ = filter_policy;
type_ = type;
interval_ = interval;
- LOG_INFO("%s -> %s type = %hhx interval = %d ms", address_.ToString().c_str(),
- peer_address.ToString().c_str(), type_,
- static_cast<int>(interval_.count()));
+ tx_power_ = tx_power;
+ LOG_INFO("%s -> %s type = %hhx interval = %d ms tx_power = 0x%hhx",
+ address_.ToString().c_str(), peer_address.ToString().c_str(), type_,
+ static_cast<int>(interval_.count()), tx_power);
}
void LeAdvertiser::Clear() {
@@ -57,7 +65,7 @@ void LeAdvertiser::Clear() {
type_ = model::packets::AdvertisementType::ADV_IND;
advertisement_.clear();
scan_response_.clear();
- interval_ = std::chrono::milliseconds(0);
+ interval_ = 0ms;
enabled_ = false;
}
@@ -77,30 +85,55 @@ void LeAdvertiser::SetScanResponse(const std::vector<uint8_t>& data) {
}
void LeAdvertiser::Enable() {
+ EnableExtended(0ms);
+ extended_ = false;
+}
+
+void LeAdvertiser::EnableExtended(std::chrono::milliseconds duration_ms) {
enabled_ = true;
- last_le_advertisement_ = std::chrono::steady_clock::now() - interval_;
+ extended_ = true;
num_events_ = 0;
- LOG_INFO("%s -> %s type = %hhx ad length %zu, scan length %zu",
- address_.ToString().c_str(), peer_address_.ToString().c_str(), type_,
- advertisement_.size(), scan_response_.size());
-}
-void LeAdvertiser::EnableExtended(
- std::chrono::steady_clock::duration duration) {
- Enable();
- if (duration != std::chrono::milliseconds(0)) {
- ending_time_ = std::chrono::steady_clock::now() + duration;
+ using Duration = std::chrono::steady_clock::duration;
+ using TimePoint = std::chrono::steady_clock::time_point;
+
+ Duration adv_direct_ind_timeout = 1280ms; // 1.28s
+ Duration adv_direct_ind_interval_low = 10000us; // 10ms
+ Duration adv_direct_ind_interval_high = 3750us; // 3.75ms
+ Duration duration = duration_ms;
+ TimePoint now = std::chrono::steady_clock::now();
+
+ switch (type_) {
+ // [Vol 6] Part B. 4.4.2.4.3 High duty cycle connectable directed advertising
+ case model::packets::AdvertisementType::ADV_DIRECT_IND:
+ duration = duration == 0ms ?
+ adv_direct_ind_timeout :
+ std::min(duration, adv_direct_ind_timeout);
+ interval_ = adv_direct_ind_interval_high;
+ break;
+
+ // [Vol 6] Part B. 4.4.2.4.2 Low duty cycle connectable directed advertising
+ case model::packets::AdvertisementType::SCAN_RESPONSE:
+ interval_ = adv_direct_ind_interval_low;
+ break;
+
+ // Duration set to parameter,
+ // interval set by Initialize().
+ default:
+ break;
}
- extended_ = true;
+
+ last_le_advertisement_ = now - interval_;
+ ending_time_ = now + duration;
+ limited_ = duration != 0ms;
+
LOG_INFO("%s -> %s type = %hhx ad length %zu, scan length %zu",
address_.ToString().c_str(), peer_address_.ToString().c_str(), type_,
advertisement_.size(), scan_response_.size());
}
void LeAdvertiser::Disable() { enabled_ = false; }
-
bool LeAdvertiser::IsEnabled() const { return enabled_; }
-
bool LeAdvertiser::IsExtended() const { return extended_; }
bool LeAdvertiser::IsConnectable() const {
@@ -110,30 +143,67 @@ bool LeAdvertiser::IsConnectable() const {
uint8_t LeAdvertiser::GetNumAdvertisingEvents() const { return num_events_; }
-std::unique_ptr<model::packets::LeAdvertisementBuilder>
-LeAdvertiser::GetAdvertisement(std::chrono::steady_clock::time_point now) {
+std::unique_ptr<bluetooth::hci::EventBuilder>
+LeAdvertiser::GetEvent(std::chrono::steady_clock::time_point now) {
+ // Advertiser disabled.
if (!enabled_) {
return nullptr;
}
- if (now - last_le_advertisement_ < interval_) {
- return nullptr;
+ // [Vol 4] Part E 7.8.9 LE Set Advertising Enable command
+ // [Vol 4] Part E 7.8.56 LE Set Extended Advertising Enable command
+ if (type_ == model::packets::AdvertisementType::ADV_DIRECT_IND &&
+ now >= ending_time_ && limited_) {
+ LOG_INFO("Directed Advertising Timeout");
+ enabled_ = false;
+ return bluetooth::hci::LeConnectionCompleteBuilder::Create(
+ ErrorCode::ADVERTISING_TIMEOUT, 0,
+ bluetooth::hci::Role::CENTRAL,
+ bluetooth::hci::AddressType::PUBLIC_DEVICE_ADDRESS,
+ bluetooth::hci::Address(), 0, 0, 0,
+ bluetooth::hci::ClockAccuracy::PPM_500);
}
- if (last_le_advertisement_ < ending_time_ && ending_time_ < now) {
+ // [Vol 4] Part E 7.8.56 LE Set Extended Advertising Enable command
+ if (extended_ && now >= ending_time_ && limited_) {
+ LOG_INFO("Extended Advertising Timeout");
enabled_ = false;
+ return bluetooth::hci::LeAdvertisingSetTerminatedBuilder::Create(
+ ErrorCode::SUCCESS, advertising_handle_, 0, num_events_);
+ }
+
+ return nullptr;
+}
+
+std::unique_ptr<model::packets::LinkLayerPacketBuilder>
+LeAdvertiser::GetAdvertisement(std::chrono::steady_clock::time_point now) {
+ if (!enabled_) {
+ return nullptr;
+ }
+
+ if (now - last_le_advertisement_ < interval_) {
return nullptr;
}
last_le_advertisement_ = now;
num_events_ += (num_events_ < 255 ? 1 : 0);
- return model::packets::LeAdvertisementBuilder::Create(
- address_.GetAddress(), peer_address_.GetAddress(),
- static_cast<model::packets::AddressType>(address_.GetAddressType()),
- type_, advertisement_);
+ if (tx_power_ == kTxPowerUnavailable) {
+ return model::packets::LeAdvertisementBuilder::Create(
+ address_.GetAddress(), peer_address_.GetAddress(),
+ static_cast<model::packets::AddressType>(address_.GetAddressType()),
+ type_, advertisement_);
+ } else {
+ uint8_t tx_power_jittered = 2 + tx_power_ - (num_events_ & 0x03);
+ return model::packets::RssiWrapperBuilder::Create(
+ address_.GetAddress(), peer_address_.GetAddress(), tx_power_jittered,
+ model::packets::LeAdvertisementBuilder::Create(
+ address_.GetAddress(), peer_address_.GetAddress(),
+ static_cast<model::packets::AddressType>(address_.GetAddressType()),
+ type_, advertisement_));
+ }
}
-std::unique_ptr<model::packets::LeScanResponseBuilder>
+std::unique_ptr<model::packets::LinkLayerPacketBuilder>
LeAdvertiser::GetScanResponse(bluetooth::hci::Address scanned,
bluetooth::hci::Address scanner) {
if (scanned != address_.GetAddress() || !enabled_) {
@@ -153,10 +223,20 @@ LeAdvertiser::GetScanResponse(bluetooth::hci::Address scanned,
case bluetooth::hci::LeScanningFilterPolicy::ACCEPT_ALL:
break;
}
- return model::packets::LeScanResponseBuilder::Create(
- address_.GetAddress(), peer_address_.GetAddress(),
- static_cast<model::packets::AddressType>(address_.GetAddressType()),
- model::packets::AdvertisementType::SCAN_RESPONSE, scan_response_);
+ if (tx_power_ == kTxPowerUnavailable) {
+ return model::packets::LeScanResponseBuilder::Create(
+ address_.GetAddress(), peer_address_.GetAddress(),
+ static_cast<model::packets::AddressType>(address_.GetAddressType()),
+ type_, advertisement_);
+ } else {
+ uint8_t tx_power_jittered = 2 + tx_power_ - (num_events_ & 0x03);
+ return model::packets::RssiWrapperBuilder::Create(
+ address_.GetAddress(), peer_address_.GetAddress(), tx_power_jittered,
+ model::packets::LeScanResponseBuilder::Create(
+ address_.GetAddress(), peer_address_.GetAddress(),
+ static_cast<model::packets::AddressType>(address_.GetAddressType()),
+ type_, advertisement_));
+ }
}
} // namespace test_vendor_lib
diff --git a/system/vendor_libs/test_vendor_lib/model/controller/le_advertiser.h b/system/vendor_libs/test_vendor_lib/model/controller/le_advertiser.h
index a9d14ab82a..37f7488b7c 100644
--- a/system/vendor_libs/test_vendor_lib/model/controller/le_advertiser.h
+++ b/system/vendor_libs/test_vendor_lib/model/controller/le_advertiser.h
@@ -40,11 +40,13 @@ class LeAdvertiser {
const std::vector<uint8_t>& scan_response,
std::chrono::steady_clock::duration interval);
- void InitializeExtended(bluetooth::hci::AddressType address_type,
+ void InitializeExtended(unsigned advertising_handle,
+ bluetooth::hci::AddressType address_type,
bluetooth::hci::AddressWithType peer_address,
bluetooth::hci::LeScanningFilterPolicy filter_policy,
model::packets::AdvertisementType type,
- std::chrono::steady_clock::duration interval);
+ std::chrono::steady_clock::duration interval,
+ uint8_t tx_power);
void SetAddress(bluetooth::hci::Address address);
@@ -52,32 +54,32 @@ class LeAdvertiser {
void SetScanResponse(const std::vector<uint8_t>& data);
- std::unique_ptr<model::packets::LeAdvertisementBuilder> GetAdvertisement(
+ // Generate LE Connection Complete or LE Extended Advertising Set Terminated
+ // events at the end of the advertising period. The advertiser is
+ // automatically disabled.
+ std::unique_ptr<bluetooth::hci::EventBuilder> GetEvent(
std::chrono::steady_clock::time_point);
- std::unique_ptr<model::packets::LeScanResponseBuilder> GetScanResponse(
+ std::unique_ptr<model::packets::LinkLayerPacketBuilder> GetAdvertisement(
+ std::chrono::steady_clock::time_point);
+
+ std::unique_ptr<model::packets::LinkLayerPacketBuilder> GetScanResponse(
bluetooth::hci::Address scanned_address,
bluetooth::hci::Address scanner_address);
void Clear();
-
void Disable();
-
void Enable();
-
- void EnableExtended(std::chrono::steady_clock::duration duration);
+ void EnableExtended(std::chrono::milliseconds duration);
bool IsEnabled() const;
-
bool IsExtended() const;
-
bool IsConnectable() const;
uint8_t GetNumAdvertisingEvents() const;
-
bluetooth::hci::AddressWithType GetAddress() const;
- private:
+private:
bluetooth::hci::AddressWithType address_{};
bluetooth::hci::AddressWithType
peer_address_{}; // For directed advertisements
@@ -87,10 +89,14 @@ class LeAdvertiser {
std::vector<uint8_t> scan_response_;
std::chrono::steady_clock::duration interval_{};
std::chrono::steady_clock::time_point ending_time_{};
+ std::chrono::steady_clock::time_point last_le_advertisement_{};
+ static constexpr uint8_t kTxPowerUnavailable = 0x7f;
+ uint8_t tx_power_{kTxPowerUnavailable};
uint8_t num_events_{0};
bool extended_{false};
bool enabled_{false};
- std::chrono::steady_clock::time_point last_le_advertisement_;
+ bool limited_{false}; // Set if the advertising set has a timeout.
+ unsigned advertising_handle_{0};
};
} // namespace test_vendor_lib
diff --git a/system/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.cc b/system/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.cc
index 2374ca02dc..e79982fa0c 100644
--- a/system/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.cc
+++ b/system/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.cc
@@ -19,7 +19,6 @@
#include <hci/hci_packets.h>
#include "crypto_toolbox/crypto_toolbox.h"
-#include "include/le_advertisement.h"
#include "os/log.h"
#include "packet/raw_builder.h"
@@ -32,6 +31,7 @@ using bluetooth::hci::EventCode;
using namespace model::packets;
using model::packets::PacketType;
+using namespace std::literals;
namespace test_vendor_lib {
@@ -51,6 +51,17 @@ static uint8_t GetRssi() {
return -(rssi);
}
+void LinkLayerController::SendLeLinkLayerPacketWithRssi(
+ Address source, Address dest, uint8_t rssi,
+ std::unique_ptr<model::packets::LinkLayerPacketBuilder> packet) {
+ std::shared_ptr<model::packets::RssiWrapperBuilder> shared_packet =
+ model::packets::RssiWrapperBuilder::Create(source, dest, rssi,
+ std::move(packet));
+ ScheduleTask(kNoDelayMs, [this, shared_packet]() {
+ send_to_remote_(shared_packet, Phy::Type::LOW_ENERGY);
+ });
+}
+
void LinkLayerController::SendLeLinkLayerPacket(
std::unique_ptr<model::packets::LinkLayerPacketBuilder> packet) {
std::shared_ptr<model::packets::LinkLayerPacketBuilder> shared_packet =
@@ -218,6 +229,20 @@ ErrorCode LinkLayerController::SendScoToRemote(
void LinkLayerController::IncomingPacket(
model::packets::LinkLayerPacketView incoming) {
ASSERT(incoming.IsValid());
+ if (incoming.GetType() == PacketType::RSSI_WRAPPER) {
+ auto rssi_wrapper = model::packets::RssiWrapperView::Create(incoming);
+ ASSERT(rssi_wrapper.IsValid());
+ auto wrapped =
+ model::packets::LinkLayerPacketView::Create(rssi_wrapper.GetPayload());
+ IncomingPacketWithRssi(wrapped, rssi_wrapper.GetRssi());
+ } else {
+ IncomingPacketWithRssi(incoming, GetRssi());
+ }
+}
+
+void LinkLayerController::IncomingPacketWithRssi(
+ model::packets::LinkLayerPacketView incoming, uint8_t rssi) {
+ ASSERT(incoming.IsValid());
auto destination_address = incoming.GetDestinationAddress();
// Match broadcasts
@@ -278,7 +303,7 @@ void LinkLayerController::IncomingPacket(
break;
case model::packets::PacketType::INQUIRY:
if (inquiry_scans_enabled_) {
- IncomingInquiryPacket(incoming);
+ IncomingInquiryPacket(incoming, rssi);
}
break;
case model::packets::PacketType::INQUIRY_RESPONSE:
@@ -307,7 +332,7 @@ void LinkLayerController::IncomingPacket(
break;
case model::packets::PacketType::LE_ADVERTISEMENT:
if (le_scan_enable_ != bluetooth::hci::OpCode::NONE || le_connect_) {
- IncomingLeAdvertisementPacket(incoming);
+ IncomingLeAdvertisementPacket(incoming, rssi);
}
break;
case model::packets::PacketType::LE_CONNECT:
@@ -341,7 +366,7 @@ void LinkLayerController::IncomingPacket(
case model::packets::PacketType::LE_SCAN_RESPONSE:
if (le_scan_enable_ != bluetooth::hci::OpCode::NONE &&
le_scan_type_ == 1) {
- IncomingLeScanResponsePacket(incoming);
+ IncomingLeScanResponsePacket(incoming, rssi);
}
break;
case model::packets::PacketType::PAGE:
@@ -403,6 +428,9 @@ void LinkLayerController::IncomingPacket(
case (model::packets::PacketType::READ_CLOCK_OFFSET_RESPONSE):
IncomingReadClockOffsetResponse(incoming);
break;
+ case (model::packets::PacketType::RSSI_WRAPPER):
+ LOG_ERROR("Dropping double-wrapped RSSI packet");
+ break;
case model::packets::PacketType::SCO_CONNECTION_REQUEST:
IncomingScoConnectionRequest(incoming);
break;
@@ -722,7 +750,7 @@ void LinkLayerController::IncomingEncryptConnectionResponse(
}
void LinkLayerController::IncomingInquiryPacket(
- model::packets::LinkLayerPacketView incoming) {
+ model::packets::LinkLayerPacketView incoming, uint8_t rssi) {
auto inquiry = model::packets::InquiryView::Create(incoming);
ASSERT(inquiry.IsValid());
@@ -741,7 +769,7 @@ void LinkLayerController::IncomingInquiryPacket(
properties_.GetAddress(), peer,
properties_.GetPageScanRepetitionMode(),
properties_.GetClassOfDevice(), properties_.GetClockOffset(),
- GetRssi()));
+ rssi));
} break;
case (model::packets::InquiryType::EXTENDED): {
SendLinkLayerPacket(
@@ -749,7 +777,7 @@ void LinkLayerController::IncomingInquiryPacket(
properties_.GetAddress(), peer,
properties_.GetPageScanRepetitionMode(),
properties_.GetClassOfDevice(), properties_.GetClockOffset(),
- GetRssi(), properties_.GetExtendedInquiryData()));
+ rssi, properties_.GetExtendedInquiryData()));
} break;
default:
@@ -1251,7 +1279,7 @@ static Address generate_rpa(
}
void LinkLayerController::IncomingLeAdvertisementPacket(
- model::packets::LinkLayerPacketView incoming) {
+ model::packets::LinkLayerPacketView incoming, uint8_t rssi) {
// TODO: Handle multiple advertisements per packet.
Address address = incoming.GetSourceAddress();
@@ -1273,7 +1301,7 @@ void LinkLayerController::IncomingLeAdvertisementPacket(
raw_builder_ptr->AddAddress(address);
raw_builder_ptr->AddOctets1(ad.size());
raw_builder_ptr->AddOctets(ad);
- raw_builder_ptr->AddOctets1(GetRssi());
+ raw_builder_ptr->AddOctets1(rssi);
if (properties_.IsUnmasked(EventCode::LE_META_EVENT)) {
send_event_(bluetooth::hci::EventBuilder::Create(
bluetooth::hci::EventCode::LE_META_EVENT,
@@ -1313,7 +1341,7 @@ void LinkLayerController::IncomingLeAdvertisementPacket(
raw_builder_ptr->AddOctets1(0); // Secondary_PHY
raw_builder_ptr->AddOctets1(0xFF); // Advertising_SID - not provided
raw_builder_ptr->AddOctets1(0x7F); // Tx_Power - Not available
- raw_builder_ptr->AddOctets1(GetRssi());
+ raw_builder_ptr->AddOctets1(rssi);
raw_builder_ptr->AddOctets2(0); // Periodic_Advertising_Interval - None
raw_builder_ptr->AddOctets1(0); // Direct_Address_Type - PUBLIC
raw_builder_ptr->AddAddress(Address::kEmpty); // Direct_Address
@@ -1801,13 +1829,12 @@ void LinkLayerController::IncomingLeScanPacket(
}
void LinkLayerController::IncomingLeScanResponsePacket(
- model::packets::LinkLayerPacketView incoming) {
+ model::packets::LinkLayerPacketView incoming, uint8_t rssi) {
auto scan_response = model::packets::LeScanResponseView::Create(incoming);
ASSERT(scan_response.IsValid());
vector<uint8_t> ad = scan_response.GetData();
auto adv_type = scan_response.GetAdvertisementType();
- auto address_type =
- static_cast<LeAdvertisement::AddressType>(scan_response.GetAddressType());
+ auto address_type = scan_response.GetAddressType();
if (le_scan_enable_ == bluetooth::hci::OpCode::LE_SET_SCAN_ENABLE) {
if (adv_type != model::packets::AdvertisementType::SCAN_RESPONSE) {
return;
@@ -1818,7 +1845,7 @@ void LinkLayerController::IncomingLeScanResponsePacket(
report.address_type_ =
static_cast<bluetooth::hci::AddressType>(address_type);
report.advertising_data_ = scan_response.GetData();
- report.rssi_ = GetRssi();
+ report.rssi_ = rssi;
if (properties_.IsUnmasked(EventCode::LE_META_EVENT) &&
properties_.GetLeEventSupported(
@@ -1844,7 +1871,7 @@ void LinkLayerController::IncomingLeScanResponsePacket(
report.advertising_sid_ = 0xFF;
report.tx_power_ = 0x7F;
report.advertising_data_ = ad;
- report.rssi_ = GetRssi();
+ report.rssi_ = rssi;
send_event_(
bluetooth::hci::LeExtendedAdvertisingReportBuilder::Create({report}));
}
@@ -2060,11 +2087,16 @@ void LinkLayerController::Close() {
void LinkLayerController::LeAdvertising() {
steady_clock::time_point now = steady_clock::now();
for (auto& advertiser : advertisers_) {
- auto ad = advertiser.GetAdvertisement(now);
- if (ad == nullptr) {
- continue;
+
+ auto event = advertiser.GetEvent(now);
+ if (event != nullptr) {
+ send_event_(std::move(event));
+ }
+
+ auto advertisement = advertiser.GetAdvertisement(now);
+ if (advertisement != nullptr) {
+ SendLeLinkLayerPacket(std::move(advertisement));
}
- SendLeLinkLayerPacket(std::move(ad));
}
}
@@ -2979,7 +3011,7 @@ ErrorCode LinkLayerController::SetLeExtendedAdvertisingParameters(
bluetooth::hci::LegacyAdvertisingProperties type,
bluetooth::hci::OwnAddressType own_address_type,
bluetooth::hci::PeerAddressType peer_address_type, Address peer,
- bluetooth::hci::AdvertisingFilterPolicy filter_policy) {
+ bluetooth::hci::AdvertisingFilterPolicy filter_policy, uint8_t tx_power) {
model::packets::AdvertisementType ad_type;
switch (type) {
case bluetooth::hci::LegacyAdvertisingProperties::ADV_IND:
@@ -2995,9 +3027,11 @@ ErrorCode LinkLayerController::SetLeExtendedAdvertisingParameters(
peer = Address::kEmpty;
break;
case bluetooth::hci::LegacyAdvertisingProperties::ADV_DIRECT_IND_HIGH:
- case bluetooth::hci::LegacyAdvertisingProperties::ADV_DIRECT_IND_LOW:
ad_type = model::packets::AdvertisementType::ADV_DIRECT_IND;
break;
+ case bluetooth::hci::LegacyAdvertisingProperties::ADV_DIRECT_IND_LOW:
+ ad_type = model::packets::AdvertisementType::SCAN_RESPONSE;
+ break;
}
auto interval_ms =
static_cast<int>((interval_max + interval_min) * 0.625 / 2);
@@ -3054,10 +3088,13 @@ ErrorCode LinkLayerController::SetLeExtendedAdvertisingParameters(
break;
}
- advertisers_[set].InitializeExtended(own_address_address_type, peer_address,
- scanning_filter_policy, ad_type,
- std::chrono::milliseconds(interval_ms));
-
+ advertisers_[set].InitializeExtended(set,
+ own_address_address_type,
+ peer_address,
+ scanning_filter_policy,
+ ad_type,
+ std::chrono::milliseconds(interval_ms),
+ tx_power);
return ErrorCode::SUCCESS;
}
@@ -3518,6 +3555,7 @@ uint8_t LinkLayerController::LeReadNumberOfSupportedAdvertisingSets() {
ErrorCode LinkLayerController::SetLeExtendedAdvertisingEnable(
bluetooth::hci::Enable enable,
const std::vector<bluetooth::hci::EnabledSet>& enabled_sets) {
+
for (const auto& set : enabled_sets) {
if (set.advertising_handle_ > advertisers_.size()) {
return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
@@ -3526,8 +3564,7 @@ ErrorCode LinkLayerController::SetLeExtendedAdvertisingEnable(
for (const auto& set : enabled_sets) {
auto handle = set.advertising_handle_;
if (enable == bluetooth::hci::Enable::ENABLED) {
- advertisers_[handle].EnableExtended(
- std::chrono::milliseconds(10 * set.duration_));
+ advertisers_[handle].EnableExtended(10ms * set.duration_);
} else {
advertisers_[handle].Disable();
}
diff --git a/system/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.h b/system/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.h
index 097e9722ad..7a9a10f2df 100644
--- a/system/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.h
+++ b/system/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.h
@@ -18,7 +18,6 @@
#include "hci/address.h"
#include "hci/hci_packets.h"
-#include "include/inquiry.h"
#include "include/phy.h"
#include "model/controller/acl_connection_handler.h"
#include "model/controller/le_advertiser.h"
@@ -97,6 +96,9 @@ class LinkLayerController {
private:
void SendDisconnectionCompleteEvent(uint16_t handle, uint8_t reason);
+ void IncomingPacketWithRssi(model::packets::LinkLayerPacketView incoming,
+ uint8_t rssi);
+
public:
void IncomingPacket(model::packets::LinkLayerPacketView incoming);
@@ -156,7 +158,7 @@ class LinkLayerController {
bluetooth::hci::LegacyAdvertisingProperties type,
bluetooth::hci::OwnAddressType own_address_type,
bluetooth::hci::PeerAddressType peer_address_type, Address peer,
- bluetooth::hci::AdvertisingFilterPolicy filter_policy);
+ bluetooth::hci::AdvertisingFilterPolicy filter_policy, uint8_t tx_power);
ErrorCode LeRemoveAdvertisingSet(uint8_t set);
ErrorCode LeClearAdvertisingSets();
void LeConnectionUpdateComplete(uint16_t handle, uint16_t interval_min,
@@ -376,6 +378,9 @@ class LinkLayerController {
void HandleIso(bluetooth::hci::IsoView iso);
protected:
+ void SendLeLinkLayerPacketWithRssi(
+ Address source, Address dest, uint8_t rssi,
+ std::unique_ptr<model::packets::LinkLayerPacketBuilder> packet);
void SendLeLinkLayerPacket(
std::unique_ptr<model::packets::LinkLayerPacketBuilder> packet);
void SendLinkLayerPacket(
@@ -386,7 +391,8 @@ class LinkLayerController {
void IncomingEncryptConnection(model::packets::LinkLayerPacketView packet);
void IncomingEncryptConnectionResponse(
model::packets::LinkLayerPacketView packet);
- void IncomingInquiryPacket(model::packets::LinkLayerPacketView packet);
+ void IncomingInquiryPacket(model::packets::LinkLayerPacketView packet,
+ uint8_t rssi);
void IncomingInquiryResponsePacket(
model::packets::LinkLayerPacketView packet);
void IncomingIoCapabilityRequestPacket(
@@ -402,8 +408,8 @@ class LinkLayerController {
model::packets::LinkLayerPacketView packet);
void IncomingKeypressNotificationPacket(
model::packets::LinkLayerPacketView packet);
- void IncomingLeAdvertisementPacket(
- model::packets::LinkLayerPacketView packet);
+ void IncomingLeAdvertisementPacket(model::packets::LinkLayerPacketView packet,
+ uint8_t rssi);
void IncomingLeConnectPacket(model::packets::LinkLayerPacketView packet);
void IncomingLeConnectCompletePacket(
model::packets::LinkLayerPacketView packet);
@@ -418,7 +424,8 @@ class LinkLayerController {
void IncomingLeReadRemoteFeaturesResponse(
model::packets::LinkLayerPacketView packet);
void IncomingLeScanPacket(model::packets::LinkLayerPacketView packet);
- void IncomingLeScanResponsePacket(model::packets::LinkLayerPacketView packet);
+ void IncomingLeScanResponsePacket(model::packets::LinkLayerPacketView packet,
+ uint8_t rssi);
void IncomingPagePacket(model::packets::LinkLayerPacketView packet);
void IncomingPageRejectPacket(model::packets::LinkLayerPacketView packet);
void IncomingPageResponsePacket(model::packets::LinkLayerPacketView packet);
diff --git a/system/vendor_libs/test_vendor_lib/model/devices/loopback.cc b/system/vendor_libs/test_vendor_lib/model/devices/loopback.cc
index c13f95d13d..de1a358771 100644
--- a/system/vendor_libs/test_vendor_lib/model/devices/loopback.cc
+++ b/system/vendor_libs/test_vendor_lib/model/devices/loopback.cc
@@ -16,7 +16,6 @@
#include "loopback.h"
-#include "le_advertisement.h"
#include "model/setup/device_boutique.h"
#include "os/log.h"
diff --git a/system/vendor_libs/test_vendor_lib/model/devices/server_port_factory.cc b/system/vendor_libs/test_vendor_lib/model/devices/server_port_factory.cc
deleted file mode 100644
index b0b2165022..0000000000
--- a/system/vendor_libs/test_vendor_lib/model/devices/server_port_factory.cc
+++ /dev/null
@@ -1,147 +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.
- */
-
-#include "server_port_factory.h"
-
-#include "os/log.h"
-#include "osi/include/osi.h"
-
-#include <netinet/in.h>
-#include <sys/socket.h>
-
-using std::vector;
-
-namespace test_vendor_lib {
-namespace net {
-
-ServerPortFactory::ServerPortFactory(int port, std::function<void(int fd)>& callback) {
- port_ = port;
- callback_ = callback;
-}
-
-int ServerPortFactory::SetUp(int port) {
- struct sockaddr_in listen_address;
- socklen_t sockaddr_in_size = sizeof(struct sockaddr_in);
- memset(&listen_address, 0, sockaddr_in_size);
-
- OSI_NO_INTR(listen_fd_ = socket(AF_INET, SOCK_STREAM, 0));
- if (listen_fd_ < 0) {
- LOG_INFO("Error creating socket for test channel.");
- return -1;
- }
-
- LOG_INFO("port: %d", port);
- listen_address.sin_family = AF_INET;
- listen_address.sin_port = htons(port);
- listen_address.sin_addr.s_addr = htonl(INADDR_ANY);
-
- if (bind(listen_fd_, reinterpret_cast<sockaddr*>(&listen_address), sockaddr_in_size) < 0) {
- LOG_INFO("Error binding test channel listener socket to address.");
- close(listen_fd_);
- return -1;
- }
-
- if (listen(listen_fd_, 1) < 0) {
- LOG_INFO("Error listening for test channel.");
- close(listen_fd_);
- return -1;
- }
- return listen_fd_;
-}
-
-void ServerPortFactory::CleanUp() {
- if (listen_fd_ == -1) {
- return;
- }
- if (close(listen_fd_)) {
- LOG_ERROR("Error closing listen_fd_.");
- }
- listen_fd_ = -1;
-}
-
-int ServerPortFactory::Accept(int listen_fd_) {
- int accept_fd = -1;
- struct sockaddr_in test_channel_address;
- socklen_t sockaddr_in_size = sizeof(struct sockaddr_in);
- memset(&test_channel_address, 0, sockaddr_in_size);
-
- OSI_NO_INTR(accept_fd = accept(listen_fd_, reinterpret_cast<sockaddr*>(&test_channel_address), &sockaddr_in_size));
- if (accept_fd < 0) {
- LOG_INFO("Error accepting test channel connection errno=%d (%s).", errno, strerror(errno));
-
- if (errno != EAGAIN && errno != EWOULDBLOCK) {
- LOG_ERROR("Closing listen_fd_ (won't try again).");
- close(listen_fd_);
- return -1;
- }
- }
-
- LOG_INFO("accept_fd = %d.", accept_fd);
-
- return accept_fd;
-}
-
-void ServerPortFactory::OnCommandReady(int fd, std::function<void(void)> unwatch) {
- uint8_t command_name_size = 0;
- read(fd, &command_name_size, 1);
- vector<uint8_t> command_name_raw;
- command_name_raw.resize(command_name_size);
- read(fd, &command_name_raw[0], command_name_size);
- std::string command_name(command_name_raw.begin(), command_name_raw.end());
-
- if (command_name == "CLOSE_TEST_CHANNEL" || command_name == "") {
- LOG_INFO("Test channel closed");
- unwatch();
- close(fd);
- return;
- }
-
- uint8_t num_args = 0;
- read(fd, &num_args, 1);
- vector<std::string> args;
- for (uint8_t i = 0; i < num_args; ++i) {
- uint8_t arg_size = 0;
- read(fd, &arg_size, 1);
- vector<uint8_t> arg;
- arg.resize(arg_size);
- read(fd, &arg[0], arg_size);
- args.push_back(std::string(arg.begin(), arg.end()));
- }
-
- command_handler_(command_name, args);
-}
-
-void ServerPortFactory::SendResponse(int fd, const std::string& response) const {
- size_t size = response.size();
- // Cap to 64K
- if (size > 0xffff) {
- size = 0xffff;
- }
- char size_buf[4] = {static_cast<uint8_t>(size & 0xff), static_cast<uint8_t>((size >> 8) & 0xff),
- static_cast<uint8_t>((size >> 16) & 0xff), static_cast<uint8_t>((size >> 24) & 0xff)};
- int written = write(fd, size_buf, 4);
- ASSERT_LOG(written == 4, "What happened? written = %d errno = %d", written, errno);
- written = write(fd, response.c_str(), size);
- ASSERT_LOG(written == static_cast<int>(size), "What happened? written = %d errno = %d", written, errno);
-}
-
-void ServerPortFactory::RegisterCommandHandler(
- const std::function<void(const std::string&, const std::vector<std::string>&)>& callback) {
- command_handler_ = callback;
-}
-
-} // namespace net
-} // namespace test_vendor_lib
diff --git a/system/vendor_libs/test_vendor_lib/model/devices/server_port_factory.h b/system/vendor_libs/test_vendor_lib/model/devices/server_port_factory.h
deleted file mode 100644
index 5f19c49180..0000000000
--- a/system/vendor_libs/test_vendor_lib/model/devices/server_port_factory.h
+++ /dev/null
@@ -1,51 +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.
- */
-
-#pragma once
-
-#include <functional>
-#include <memory>
-#include <string>
-#include <vector>
-
-namespace test_vendor_lib {
-namespace net {
-
-// Starts a server and calls the registered lambda for each connection.
-class ServerPortFactory {
- public:
- // Opens a server port and sets the listen file descriptor.
- ServerPortFactory(int port, std::function<void(int fd)>& on_connection);
-
- // Closes the port (if succesfully opened in SetUp).
- ~ServerPortFactory() {}
-
- // Waits for a connection request and returns the file descriptor to watch.
- // Returns -1 on an error.
- void Accept(int listen_fd);
-
- private:
- std::function<void(int fd)> on_connection_;
-
- int port;
- int listen_fd_ = -1;
-
- ServerPortFactory(const ServerPortFactory&) = delete;
- ServerPortFactory& operator=(const ServerPortFactory&) = delete;
-};
-
-} // namespace net
-} // namespace test_vendor_lib
diff --git a/system/vendor_libs/test_vendor_lib/model/devices/sniffer.cc b/system/vendor_libs/test_vendor_lib/model/devices/sniffer.cc
index efdca87487..edeb22d152 100644
--- a/system/vendor_libs/test_vendor_lib/model/devices/sniffer.cc
+++ b/system/vendor_libs/test_vendor_lib/model/devices/sniffer.cc
@@ -47,10 +47,28 @@ void Sniffer::IncomingPacket(model::packets::LinkLayerPacketView packet) {
if (!match_source && !match_dest) {
return;
}
- LOG_INFO("%s %s -> %s (Type %s)",
- (match_source ? (match_dest ? "<->" : "<--") : "-->"),
- source.ToString().c_str(), dest.ToString().c_str(),
- model::packets::PacketTypeText(packet.GetType()).c_str());
+ model::packets::PacketType packet_type = packet.GetType();
+
+ if (packet_type == model::packets::PacketType::RSSI_WRAPPER) {
+ auto wrapper_view = model::packets::RssiWrapperView::Create(packet);
+ ASSERT(wrapper_view.IsValid());
+ auto wrapped_view =
+ model::packets::LinkLayerPacketView::Create(wrapper_view.GetPayload());
+ ASSERT(wrapped_view.IsValid());
+ LOG_INFO(
+ "%s %s -> %s (Type %s wrapping %s)",
+ (match_source ? (match_dest ? "<->" : "<--") : "-->"),
+ source.ToString().c_str(), dest.ToString().c_str(),
+ model::packets::PacketTypeText(packet_type).c_str(),
+ (packet_type == model::packets::PacketType::RSSI_WRAPPER
+ ? model::packets::PacketTypeText(wrapped_view.GetType()).c_str()
+ : ""));
+ } else {
+ LOG_INFO("%s %s -> %s (Type %s)",
+ (match_source ? (match_dest ? "<->" : "<--") : "-->"),
+ source.ToString().c_str(), dest.ToString().c_str(),
+ model::packets::PacketTypeText(packet_type).c_str());
+ }
}
} // namespace test_vendor_lib
diff --git a/system/vendor_libs/test_vendor_lib/net/posix/posix_async_socket.cc b/system/vendor_libs/test_vendor_lib/net/posix/posix_async_socket.cc
index c5e8af3a94..1d57d10f34 100644
--- a/system/vendor_libs/test_vendor_lib/net/posix/posix_async_socket.cc
+++ b/system/vendor_libs/test_vendor_lib/net/posix/posix_async_socket.cc
@@ -41,7 +41,7 @@ PosixAsyncSocket::PosixAsyncSocket(int fd, AsyncManager* am)
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
flags = fcntl(fd, F_GETFD);
- fcntl(fd, F_SETFD, flags | O_CLOEXEC);
+ fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
#ifdef SO_NOSIGPIPE
// Disable SIGPIPE generation on Darwin.
diff --git a/system/vendor_libs/test_vendor_lib/packets/link_layer_packets.pdl b/system/vendor_libs/test_vendor_lib/packets/link_layer_packets.pdl
index 0d0e1e1772..c1336e7a2d 100644
--- a/system/vendor_libs/test_vendor_lib/packets/link_layer_packets.pdl
+++ b/system/vendor_libs/test_vendor_lib/packets/link_layer_packets.pdl
@@ -56,6 +56,7 @@ enum PacketType : 8 {
SCO_CONNECTION_REQUEST = 0x30,
SCO_CONNECTION_RESPONSE = 0x31,
SCO_DISCONNECT = 0x32,
+ RSSI_WRAPPER = 0x33,
}
packet LinkLayerPacket {
@@ -141,11 +142,11 @@ enum AddressType : 8 {
}
enum AdvertisementType : 8 {
- ADV_IND = 0, // Connectable and scannable
- ADV_DIRECT_IND = 1, // Connectable directed
- ADV_SCAN_IND = 2, // Scannable undirected
- ADV_NONCONN_IND = 3, // Non connectable undirected
- SCAN_RESPONSE = 4,
+ ADV_IND = 0, // Connectable and scannable
+ ADV_DIRECT_IND = 1, // Connectable directed, high duty cycle
+ ADV_SCAN_IND = 2, // Scannable undirected
+ ADV_NONCONN_IND = 3, // Non connectable undirected
+ SCAN_RESPONSE = 4, // Aliased with connectable directed, low duty cycle
}
packet LeAdvertisement : LinkLayerPacket (type = LE_ADVERTISEMENT) {
@@ -406,3 +407,8 @@ packet ScoConnectionResponse : LinkLayerPacket (type = SCO_CONNECTION_RESPONSE)
packet ScoDisconnect : LinkLayerPacket (type = SCO_DISCONNECT) {
reason : 8,
}
+
+packet RssiWrapper : LinkLayerPacket (type = RSSI_WRAPPER) {
+ rssi : 8,
+ _payload_,
+}
diff --git a/system/vendor_libs/test_vendor_lib/test/iterator_test.cc b/system/vendor_libs/test_vendor_lib/test/iterator_test.cc
deleted file mode 100644
index 0e7b67cf3a..0000000000
--- a/system/vendor_libs/test_vendor_lib/test/iterator_test.cc
+++ /dev/null
@@ -1,232 +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 "hci_packet.h"
-#include "l2cap_test_packets.h"
-
-#include <gtest/gtest.h>
-#include <memory>
-
-using std::unique_ptr;
-using std::vector;
-namespace test_vendor_lib {
-
-class TestPacket : public HciPacket {
- public:
- static std::shared_ptr<TestPacket> make_new_packet(vector<uint8_t> v) {
- return std::shared_ptr<TestPacket>(new TestPacket(v));
- }
- size_t get_length() {
- return test_vector_.size();
- }
- uint8_t& get_at_index(size_t index) {
- return test_vector_[index];
- }
-
- private:
- TestPacket(vector<uint8_t> v) {
- test_vector_ = v;
- }
- vector<uint8_t> test_vector_;
-};
-
-class IteratorTest : public ::testing::Test {
- public:
- IteratorTest() = default;
- ~IteratorTest() override = default;
-
- void SetUp() override {
- packet = TestPacket::make_new_packet(complete_l2cap_packet);
- }
-
- void TearDown() override {
- packet.reset();
- }
-
- std::shared_ptr<TestPacket> packet;
-};
-
-TEST_F(IteratorTest, extractTest) {
- Iterator general_case = packet->get_begin();
-
- ASSERT_EQ(0x95, general_case.extract<uint8_t>());
- ASSERT_EQ(0x471f, general_case.extract<uint16_t>());
- ASSERT_EQ(0x951f0200u, general_case.extract<uint32_t>());
- ASSERT_EQ(0x33000101000000cbu, general_case.extract<uint64_t>());
-}
-
-TEST_F(IteratorTest, extractBoundsDeathTest) {
- Iterator bounds_test = packet->get_end();
-
- ASSERT_DEATH(bounds_test.extract<uint8_t>(), "");
- ASSERT_DEATH(bounds_test.extract<uint16_t>(), "");
- ASSERT_DEATH(bounds_test.extract<uint32_t>(), "");
- ASSERT_DEATH(bounds_test.extract<uint64_t>(), "");
-}
-
-TEST_F(IteratorTest, dereferenceDeathTest) {
- Iterator dereference_test = packet->get_end();
-
- ASSERT_EQ(0x45, *(dereference_test - static_cast<size_t>(1)));
- ASSERT_DEATH(*dereference_test, "");
-}
-TEST_F(IteratorTest, plusEqTest) {
- Iterator plus_eq = packet->get_begin();
- for (size_t i = 0; i < complete_l2cap_packet.size(); i += 2) {
- ASSERT_EQ(complete_l2cap_packet[i], *plus_eq)
- << "+= test: Dereferenced iterator does not equal expected at index " << i;
- plus_eq += 2;
- }
-}
-
-TEST_F(IteratorTest, preIncrementTest) {
- Iterator plus_plus = packet->get_begin();
- for (size_t i = 0; i < complete_l2cap_packet.size() - 1; i++) {
- ASSERT_EQ(complete_l2cap_packet[i + 1], *(++plus_plus))
- << "Pre-increment test: Dereferenced iterator does not equal expected "
- << "at index " << i;
- }
-}
-
-TEST_F(IteratorTest, postIncrementTest) {
- Iterator plus_plus = packet->get_begin();
- for (size_t i = 0; i < complete_l2cap_packet.size(); i++) {
- ASSERT_EQ(complete_l2cap_packet[i], *(plus_plus++))
- << "Post-increment test: Dereferenced iterator does not equal expected "
- << "at index " << i;
- }
-}
-
-TEST_F(IteratorTest, additionTest) {
- Iterator plus = packet->get_begin();
- for (size_t i = 0; i < complete_l2cap_packet.size(); i++) {
- ASSERT_EQ(complete_l2cap_packet[i], *plus)
- << "+ test: Dereferenced iterator does not equal expected at index " << i;
- plus = plus + static_cast<size_t>(1);
- }
-}
-
-TEST_F(IteratorTest, minusEqTest) {
- Iterator minus_eq = packet->get_end();
- minus_eq -= 1;
- for (size_t i = complete_l2cap_packet.size() - 1; i > 0; i -= 2) {
- ASSERT_EQ(complete_l2cap_packet[i], *minus_eq)
- << "-= test: Dereferenced iterator does not equal expected at index " << i;
- minus_eq -= 2;
- }
-}
-
-TEST_F(IteratorTest, preDecrementTest) {
- Iterator minus_minus = packet->get_end();
- for (size_t i = complete_l2cap_packet.size(); i > 0; i--) {
- ASSERT_EQ(complete_l2cap_packet[i - 1], *(--minus_minus))
- << "Pre-decrement test: Dereferenced iterator does not equal expected "
- << "at index " << i;
- }
-}
-
-TEST_F(IteratorTest, postDecrementTest) {
- Iterator minus_minus = packet->get_end();
- minus_minus--;
- for (size_t i = complete_l2cap_packet.size() - 1; i > 0; i--) {
- ASSERT_EQ(complete_l2cap_packet[i], *(minus_minus--))
- << "Post-decrement test: Dereferenced iterator does not equal expected "
- << "at index " << i;
- }
-}
-
-TEST_F(IteratorTest, subtractionTest) {
- Iterator minus = packet->get_end();
- minus = minus - static_cast<size_t>(1);
- for (size_t i = complete_l2cap_packet.size() - 1; i > 0; i--) {
- ASSERT_EQ(complete_l2cap_packet[i], *minus)
- << "- test: Dereferenced iterator does not equal expected at index " << i;
- minus = minus - static_cast<size_t>(1);
- }
-}
-
-TEST_F(IteratorTest, plusEqBoundsTest) {
- Iterator plus_eq = packet->get_end();
- plus_eq--;
- for (size_t i = 0; i < 100; i++) {
- plus_eq += i;
- ASSERT_EQ(packet->get_end(), plus_eq) << "+= test: Iterator exceeded the upper bound set by get_length()";
- }
-}
-
-TEST_F(IteratorTest, preIncrementBoundsTest) {
- Iterator plus_plus = packet->get_end();
- plus_plus--;
- for (size_t i = 0; i < 100; i++) {
- ASSERT_EQ(packet->get_end(), ++plus_plus) << "Pre-increment test: Iterator exceeded the upper bound set "
- "by get_length()";
- }
-}
-
-TEST_F(IteratorTest, postIncrementBoundsTest) {
- Iterator plus_plus = packet->get_end();
- plus_plus--;
- for (size_t i = 0; i < 100; i++) {
- ASSERT_EQ(packet->get_end(), plus_plus++) << "Post-increment test: Iterator exceeded the upper bound set "
- "by get_length()";
- }
-}
-
-TEST_F(IteratorTest, additionBoundsTest) {
- Iterator plus = packet->get_end();
- plus--;
- for (size_t i = 0; i < 100; i++) {
- plus = plus + static_cast<size_t>(i);
- ASSERT_EQ(packet->get_end(), plus) << "+ test: Iterator exceeded the upper bound set by get_length()";
- }
-}
-
-TEST_F(IteratorTest, minusEqBoundsTest) {
- Iterator minus_eq = packet->get_begin();
- for (size_t i = 0; i < 100; i++) {
- minus_eq -= i;
- ASSERT_EQ(complete_l2cap_packet[0], *minus_eq) << "-= test: Iterator is less than the lower bound set by "
- "packet->get_begin()";
- }
-}
-
-TEST_F(IteratorTest, preDecrementBoundsTest) {
- Iterator minus_minus = packet->get_begin();
- for (size_t i = 0; i < 100; i++) {
- ASSERT_EQ(complete_l2cap_packet[0], *(--minus_minus))
- << "Pre-decrement test: Iterator is less than the lower bound set by "
- "packet->get_begin()";
- }
-}
-
-TEST_F(IteratorTest, postDecrementBoundsTest) {
- Iterator minus_minus = packet->get_begin();
- for (size_t i = 0; i < 100; i++) {
- ASSERT_EQ(complete_l2cap_packet[0], *(minus_minus--))
- << "Post-decrement test: Iterator is less than the lower bound set by "
- "packet->get_begin()";
- }
-}
-
-TEST_F(IteratorTest, subtractionBoundsTest) {
- Iterator minus = packet->get_begin();
- for (size_t i = 0; i < 100; i++) {
- minus = minus - static_cast<size_t>(i);
- ASSERT_EQ(complete_l2cap_packet[0], *minus) << "- test: Iterator is less than the lower bound set "
- "by packet->get_begin()";
- }
-}
-}; // namespace test_vendor_lib
diff --git a/system/vendor_libs/test_vendor_lib/test/l2cap_sdu_test.cc b/system/vendor_libs/test_vendor_lib/test/l2cap_sdu_test.cc
deleted file mode 100644
index 7aa0ec6bd3..0000000000
--- a/system/vendor_libs/test_vendor_lib/test/l2cap_sdu_test.cc
+++ /dev/null
@@ -1,122 +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 "l2cap_sdu.h"
-
-#include <gtest/gtest.h>
-#include <memory>
-
-#include "l2cap_test_packets.h"
-
-using std::vector;
-
-namespace test_vendor_lib {
-
-std::shared_ptr<L2capSdu> packet_1 = L2capSdu::L2capSduConstructor(l2cap_test_packet_1);
-std::shared_ptr<L2capSdu> packet_2 = L2capSdu::L2capSduConstructor(l2cap_test_packet_2);
-std::shared_ptr<L2capSdu> packet_3 = L2capSdu::L2capSduConstructor(l2cap_test_packet_3);
-std::shared_ptr<L2capSdu> packet_4 = L2capSdu::L2capSduConstructor(l2cap_test_packet_4);
-std::shared_ptr<L2capSdu> packet_5 = L2capSdu::L2capSduConstructor(l2cap_test_packet_5);
-std::shared_ptr<L2capSdu> packet_6 = L2capSdu::L2capSduConstructor(l2cap_test_packet_6);
-std::shared_ptr<L2capSdu> packet_7 = L2capSdu::L2capSduConstructor(l2cap_test_packet_7);
-std::shared_ptr<L2capSdu> packet_8 = L2capSdu::L2capSduConstructor(l2cap_test_packet_8);
-std::shared_ptr<L2capSdu> packet_9 = L2capSdu::L2capSduConstructor(l2cap_test_packet_9);
-
-class L2capSduTest : public ::testing::Test {
- public:
- L2capSduTest(){};
-
- ~L2capSduTest() override = default;
-
-}; // L2capSduTest
-
-TEST_F(L2capSduTest, getFcsTest) {
- EXPECT_EQ(0x72aa, packet_1->get_fcs());
- EXPECT_EQ(0x5b57, packet_2->get_fcs());
- EXPECT_EQ(0xe644, packet_3->get_fcs());
- EXPECT_EQ(0x21b0, packet_4->get_fcs());
- EXPECT_EQ(0xae96, packet_5->get_fcs());
- EXPECT_EQ(0x9254, packet_6->get_fcs());
- EXPECT_EQ(0xf6fa, packet_7->get_fcs());
- EXPECT_EQ(0x1da4, packet_8->get_fcs());
- EXPECT_EQ(0x781a, packet_9->get_fcs());
-}
-
-TEST_F(L2capSduTest, getPayloadLengthTest) {
- EXPECT_EQ(l2cap_test_packet_1.size() - 4, packet_1->get_payload_length());
- EXPECT_EQ(l2cap_test_packet_2.size() - 4, packet_2->get_payload_length());
- EXPECT_EQ(l2cap_test_packet_3.size() - 4, packet_3->get_payload_length());
- EXPECT_EQ(l2cap_test_packet_4.size() - 4, packet_4->get_payload_length());
- EXPECT_EQ(l2cap_test_packet_5.size() - 4, packet_5->get_payload_length());
- EXPECT_EQ(l2cap_test_packet_6.size() - 4, packet_6->get_payload_length());
- EXPECT_EQ(l2cap_test_packet_7.size() - 4, packet_7->get_payload_length());
- EXPECT_EQ(l2cap_test_packet_8.size() - 4, packet_8->get_payload_length());
- EXPECT_EQ(l2cap_test_packet_9.size() - 4, packet_9->get_payload_length());
-}
-
-TEST_F(L2capSduTest, calculateFcsTest) {
- EXPECT_EQ(0x72aa, packet_1->calculate_fcs());
- EXPECT_EQ(0x5b57, packet_2->calculate_fcs());
- EXPECT_EQ(0xe644, packet_3->calculate_fcs());
- EXPECT_EQ(0x21b0, packet_4->calculate_fcs());
- EXPECT_EQ(0xae96, packet_5->calculate_fcs());
- EXPECT_EQ(0x9254, packet_6->calculate_fcs());
- EXPECT_EQ(0xf6fa, packet_7->calculate_fcs());
- EXPECT_EQ(0x1da4, packet_8->calculate_fcs());
- EXPECT_EQ(0x781a, packet_9->calculate_fcs());
-}
-
-TEST_F(L2capSduTest, getControlsTest) {
- EXPECT_EQ(0x4102, packet_1->get_controls());
- EXPECT_EQ(0xc104, packet_2->get_controls());
- EXPECT_EQ(0xc106, packet_3->get_controls());
- EXPECT_EQ(0xc108, packet_4->get_controls());
- EXPECT_EQ(0xc10a, packet_5->get_controls());
- EXPECT_EQ(0xc10c, packet_6->get_controls());
- EXPECT_EQ(0xc10e, packet_7->get_controls());
- EXPECT_EQ(0xc110, packet_8->get_controls());
- EXPECT_EQ(0x8112, packet_9->get_controls());
-}
-
-TEST_F(L2capSduTest, getTotalLengthTest) {
- EXPECT_EQ(0x1f95, packet_1->get_total_l2cap_length());
-}
-
-TEST_F(L2capSduTest, getVectorSizeTest) {
- EXPECT_EQ(l2cap_test_packet_1.size(), packet_1->get_vector_size());
- EXPECT_EQ(l2cap_test_packet_2.size(), packet_2->get_vector_size());
- EXPECT_EQ(l2cap_test_packet_3.size(), packet_3->get_vector_size());
- EXPECT_EQ(l2cap_test_packet_4.size(), packet_4->get_vector_size());
- EXPECT_EQ(l2cap_test_packet_5.size(), packet_5->get_vector_size());
- EXPECT_EQ(l2cap_test_packet_6.size(), packet_6->get_vector_size());
- EXPECT_EQ(l2cap_test_packet_7.size(), packet_7->get_vector_size());
- EXPECT_EQ(l2cap_test_packet_8.size(), packet_8->get_vector_size());
- EXPECT_EQ(l2cap_test_packet_9.size(), packet_9->get_vector_size());
-}
-
-TEST_F(L2capSduTest, getCidTest) {
- EXPECT_EQ(0x0047, packet_1->get_channel_id());
- EXPECT_EQ(0x0047, packet_2->get_channel_id());
- EXPECT_EQ(0x0047, packet_3->get_channel_id());
- EXPECT_EQ(0x0047, packet_4->get_channel_id());
- EXPECT_EQ(0x0047, packet_5->get_channel_id());
- EXPECT_EQ(0x0047, packet_6->get_channel_id());
- EXPECT_EQ(0x0047, packet_7->get_channel_id());
- EXPECT_EQ(0x0047, packet_8->get_channel_id());
- EXPECT_EQ(0x0047, packet_9->get_channel_id());
-}
-
-} // namespace test_vendor_lib
diff --git a/system/vendor_libs/test_vendor_lib/test/l2cap_test.cc b/system/vendor_libs/test_vendor_lib/test/l2cap_test.cc
deleted file mode 100644
index b218287943..0000000000
--- a/system/vendor_libs/test_vendor_lib/test/l2cap_test.cc
+++ /dev/null
@@ -1,517 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2017 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.
- *
- ******************************************************************************/
-
-#include "hci_packet.h"
-#include "l2cap_packet.h"
-#include "l2cap_test_packets.h"
-
-#include <gtest/gtest.h>
-#include <memory>
-
-using std::shared_ptr;
-using std::vector;
-
-namespace test_vendor_lib {
-
-class TestPacket : public HciPacket {
- public:
- TestPacket(const std::vector<uint8_t>& packet) {
- complete_packet_ = packet;
- }
- TestPacket() = default;
-
- private:
- std::vector<uint8_t> complete_packet_;
- size_t get_length() {
- return complete_packet_.size();
- }
- uint8_t& get_at_index(size_t index) {
- return complete_packet_[index];
- }
-};
-
-class L2capTest : public ::testing::Test {
- public:
- std::shared_ptr<L2capSdu> update_fcs(vector<uint8_t> sdu) {
- sdu.resize(sdu.size() - 2);
-
- return L2capSdu::L2capSduBuilder(sdu);
- }
-
- void compare_packets(shared_ptr<HciPacket> expected, shared_ptr<HciPacket> received) {
- Iterator expected_begin = expected->get_begin();
- Iterator expected_end = expected->get_end();
-
- Iterator received_begin = received->get_begin();
- Iterator received_end = received->get_end();
-
- ASSERT_EQ(expected_end - expected_begin, received_end - received_begin);
-
- while (expected_begin < expected_end) {
- ASSERT_EQ(*expected_begin, *received_begin);
- expected_begin++;
- received_begin++;
- }
- }
-};
-
-TEST_F(L2capTest, assembleGoodPackets) {
- vector<std::shared_ptr<L2capSdu> > test_packet;
-
- // Test 1: Pass correct packets.
- test_packet.push_back(L2capSdu::L2capSduConstructor(good_sdu[0]));
- test_packet.push_back(L2capSdu::L2capSduConstructor(good_sdu[1]));
- test_packet.push_back(L2capSdu::L2capSduConstructor(good_sdu[2]));
-
- shared_ptr<L2capPacket> test_1 = L2capPacket::assemble(test_packet);
- ASSERT_NE(test_1, nullptr);
-
- shared_ptr<TestPacket> expected(new TestPacket(good_l2cap_packet));
-
- compare_packets(expected, test_1);
-
- test_packet.clear();
-
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_1));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_2));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_3));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_4));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_5));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_6));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_7));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_8));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_9));
-
- test_1 = L2capPacket::assemble(test_packet);
- ASSERT_NE(test_1, nullptr);
-
- expected.reset(new TestPacket(complete_l2cap_packet));
- compare_packets(expected, test_1);
-
- test_packet.clear();
-}
-
-TEST_F(L2capTest, assembleOutofOrderPackets) {
- vector<std::shared_ptr<L2capSdu> > test_packet;
-
- // Test 2: Pass out of order packets.
- test_packet.push_back(L2capSdu::L2capSduConstructor(good_sdu[1]));
- test_packet.push_back(L2capSdu::L2capSduConstructor(good_sdu[0]));
- test_packet.push_back(L2capSdu::L2capSduConstructor(good_sdu[2]));
-
- shared_ptr<L2capPacket> test_2 = L2capPacket::assemble(test_packet);
- EXPECT_EQ(test_2, nullptr);
-
- test_packet.clear();
-
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_1));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_3));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_2));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_6));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_5));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_4));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_8));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_7));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_9));
-
- test_2 = L2capPacket::assemble(test_packet);
- EXPECT_EQ(test_2, nullptr);
-
- test_packet.clear();
-}
-
-TEST_F(L2capTest, assembleBadControlBytes) {
- vector<std::shared_ptr<L2capSdu> > test_packet;
-
- // Test 3: Pass packets missing the finished control bytes.
- test_packet.push_back(L2capSdu::L2capSduConstructor(good_sdu[0]));
- test_packet.push_back(L2capSdu::L2capSduConstructor(good_sdu[1]));
-
- shared_ptr<L2capPacket> test_3 = L2capPacket::assemble(test_packet);
- EXPECT_EQ(test_3, nullptr);
-
- test_packet.clear();
-
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_1));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_2));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_3));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_4));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_5));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_6));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_7));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_8));
-
- test_3 = L2capPacket::assemble(test_packet);
- EXPECT_EQ(test_3, nullptr);
-
- test_packet.clear();
-}
-
-TEST_F(L2capTest, assembleBadFCS) {
- vector<std::shared_ptr<L2capSdu> > test_packet;
-
- // Test 4: Pass packets with incorrect frame check sequences.
- test_packet.push_back(L2capSdu::L2capSduConstructor(good_sdu[0]));
- good_sdu[1][good_sdu[1].size() - 1]++;
- test_packet.push_back(L2capSdu::L2capSduConstructor(good_sdu[1]));
- good_sdu[1][good_sdu[1].size() - 1]--;
- test_packet.push_back(L2capSdu::L2capSduConstructor(good_sdu[2]));
-
- shared_ptr<L2capPacket> test_4 = L2capPacket::assemble(test_packet);
- EXPECT_EQ(test_4, nullptr);
-
- test_packet.clear();
-
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_1));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_2));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_3));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_4));
- l2cap_test_packet_5[l2cap_test_packet_5.size() - 1]++;
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_5));
- l2cap_test_packet_5[l2cap_test_packet_5.size() - 1]--;
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_6));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_7));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_8));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_9));
-
- test_4 = L2capPacket::assemble(test_packet);
- EXPECT_EQ(test_4, nullptr);
-
- test_packet.clear();
-}
-
-TEST_F(L2capTest, assembleEmptyPayload) {
- vector<std::shared_ptr<L2capSdu> > test_packet;
-
- // Test 5: Pass a packet with an empty payload.
- test_packet.push_back(L2capSdu::L2capSduConstructor(empty_sdu_payload[0]));
- test_packet.push_back(L2capSdu::L2capSduConstructor(empty_sdu_payload[1]));
-
- shared_ptr<L2capPacket> test_5 = L2capPacket::assemble(test_packet);
- ASSERT_NE(test_5, nullptr);
-
- shared_ptr<TestPacket> expected(new TestPacket(empty_l2cap_payload));
- compare_packets(expected, test_5);
-
- test_packet.clear();
-}
-
-TEST_F(L2capTest, assembleAllStartingControlError) {
- vector<std::shared_ptr<L2capSdu> > test_packet;
-
- // Test 6: Pass a SDU with all the control bytes set to as the starting bytes.
- test_packet.push_back(L2capSdu::L2capSduConstructor(all_first_packet[0]));
- test_packet.push_back(L2capSdu::L2capSduConstructor(all_first_packet[1]));
- test_packet.push_back(L2capSdu::L2capSduConstructor(all_first_packet[2]));
-
- shared_ptr<L2capPacket> test_6 = L2capPacket::assemble(test_packet);
- EXPECT_EQ(test_6, nullptr);
-
- test_packet.clear();
-}
-
-TEST_F(L2capTest, assembleBadCID) {
- vector<std::shared_ptr<L2capSdu> > test_packet;
-
- // Test 7: Pass SDUs with mixed channel ids.
- test_packet.push_back(L2capSdu::L2capSduConstructor(good_sdu[0]));
- good_sdu[1][2]++;
- test_packet.push_back(update_fcs(good_sdu[1]));
- good_sdu[1][2]--;
- test_packet.push_back(L2capSdu::L2capSduConstructor(good_sdu[2]));
-
- shared_ptr<L2capPacket> test_7 = L2capPacket::assemble(test_packet);
- EXPECT_EQ(test_7, nullptr);
-
- test_packet.clear();
-
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_1));
- l2cap_test_packet_2[2]++;
- test_packet.push_back((update_fcs(l2cap_test_packet_2)));
- l2cap_test_packet_2[2]--;
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_3));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_4));
- l2cap_test_packet_5[2]++;
- test_packet.push_back((update_fcs(l2cap_test_packet_5)));
- l2cap_test_packet_5[2]--;
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_6));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_7));
- l2cap_test_packet_8[2]--;
- test_packet.push_back((update_fcs(l2cap_test_packet_8)));
- l2cap_test_packet_8[2]++;
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_9));
-
- test_7 = L2capPacket::assemble(test_packet);
- EXPECT_EQ(test_7, nullptr);
-
- test_packet.clear();
-}
-
-TEST_F(L2capTest, assembleUnsegmentedSDU) {
- vector<std::shared_ptr<L2capSdu> > test_packet;
-
- // Test 8: Pass a complete l2cap packet.
- test_packet.push_back(L2capSdu::L2capSduConstructor(one_sdu[0]));
-
- shared_ptr<L2capPacket> test_8 = L2capPacket::assemble(test_packet);
- EXPECT_NE(test_8, nullptr);
-
- test_packet.clear();
-}
-
-TEST_F(L2capTest, assembleBadTxSeq) {
- vector<std::shared_ptr<L2capSdu> > test_packet;
-
- // Test 9: Pass SDUs with incorrect TxSeq.
- good_sdu[0][4] += 4;
- test_packet.push_back((update_fcs(good_sdu[0])));
- good_sdu[0][4] -= 4;
- test_packet.push_back(L2capSdu::L2capSduConstructor(good_sdu[1]));
- test_packet.push_back(L2capSdu::L2capSduConstructor(good_sdu[2]));
-
- shared_ptr<L2capPacket> test_9 = L2capPacket::assemble(test_packet);
- EXPECT_EQ(test_9, nullptr);
-
- test_packet.clear();
-}
-
-TEST_F(L2capTest, assembleBadTotalSDULength) {
- vector<std::shared_ptr<L2capSdu> > test_packet;
-
- // Test 10: Pass SDUs with an incorrect total SDU length
- good_sdu[0][7]++;
- test_packet.push_back((update_fcs(good_sdu[0])));
- good_sdu[0][7]--;
- test_packet.push_back(L2capSdu::L2capSduConstructor(good_sdu[1]));
- test_packet.push_back(L2capSdu::L2capSduConstructor(good_sdu[2]));
-
- shared_ptr<L2capPacket> test_10 = L2capPacket::assemble(test_packet);
- EXPECT_EQ(test_10, nullptr);
-
- test_packet.clear();
-
- l2cap_test_packet_1[6]++;
- test_packet.push_back((update_fcs(l2cap_test_packet_1)));
- l2cap_test_packet_1[6]--;
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_2));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_3));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_4));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_5));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_6));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_7));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_8));
- test_packet.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_9));
-
- test_10 = L2capPacket::assemble(test_packet);
-
- EXPECT_EQ(test_10, nullptr);
-
- test_packet.clear();
-}
-
-// Begin Fragment Test1
-TEST_F(L2capTest, fragmentSmallSegmentTest) {
- std::vector<std::shared_ptr<L2capSdu> > sdu;
- std::shared_ptr<L2capPacket> l2cap_expected;
- std::shared_ptr<L2capPacket> l2cap_received;
-
- sdu.push_back(L2capSdu::L2capSduConstructor(good_sdu[0]));
- sdu.push_back(L2capSdu::L2capSduConstructor(good_sdu[1]));
- sdu.push_back(L2capSdu::L2capSduConstructor(good_sdu[2]));
-
- l2cap_expected = L2capPacket::assemble(sdu);
-
- sdu.clear();
-
- // Test1: Small segments
- sdu = l2cap_expected->fragment(16, 0x02, 0x41);
-
- l2cap_received = L2capPacket::assemble(sdu);
- ASSERT_NE(l2cap_received, nullptr) << "packet reassembly failed after fragment" << std::endl
- << "Test1: Small Segment request" << std::endl
- << "sdu used: good_sdu" << std::endl
- << "function call: fragment(16, 0x02, 0x41)" << std::endl;
-
- compare_packets(l2cap_expected, l2cap_received);
-
- sdu.clear();
- l2cap_expected.reset();
- l2cap_received.reset();
-} // End Fragment Test1
-
-// Begin Fragment Test2
-TEST_F(L2capTest, fragmentLargeSegmentTest) {
- std::vector<std::shared_ptr<L2capSdu> > sdu;
- std::shared_ptr<L2capPacket> l2cap_expected;
- std::shared_ptr<L2capPacket> l2cap_received;
-
- sdu.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_1));
- sdu.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_2));
- sdu.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_3));
- sdu.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_4));
- sdu.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_5));
- sdu.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_6));
- sdu.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_7));
- sdu.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_8));
- sdu.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_9));
-
- l2cap_expected = L2capPacket::assemble(sdu);
-
- sdu.clear();
-
- // Test2: Large Segments
- sdu = l2cap_expected->fragment(1024, 0x02, 0x41);
-
- l2cap_received = L2capPacket::assemble(sdu);
- ASSERT_NE(l2cap_received, nullptr) << "packet reassembly failed after fragment" << std::endl
- << "Test2: Large Segment request" << std::endl
- << "sdu used: l2cap_test_packet[1-9]" << std::endl
- << "function call: fragment(1024, 0x02, 0x41)" << std::endl;
-
- compare_packets(l2cap_expected, l2cap_received);
-
- sdu.clear();
- l2cap_expected.reset();
- l2cap_received.reset();
-} // End Fragment Test2
-
-// Begin Fragment Test3
-TEST_F(L2capTest, fragmentTxSeqTest) {
- std::vector<std::shared_ptr<L2capSdu> > sdu;
- std::shared_ptr<L2capPacket> l2cap_expected;
- std::shared_ptr<L2capPacket> l2cap_received;
-
- sdu.push_back(L2capSdu::L2capSduConstructor(good_sdu[0]));
- sdu.push_back(L2capSdu::L2capSduConstructor(good_sdu[1]));
- sdu.push_back(L2capSdu::L2capSduConstructor(good_sdu[2]));
-
- l2cap_expected = L2capPacket::assemble(sdu);
-
- sdu.clear();
-
- // Test3: Non-zero starting TxSeq
- sdu = l2cap_expected->fragment(24, 0x08, 0x41);
-
- l2cap_received = L2capPacket::assemble(sdu);
- ASSERT_NE(l2cap_received, nullptr) << "packet reassembly failed after fragment" << std::endl
- << "Test3: Non-zero starting TxSeq" << std::endl
- << "sdu used: good_sdu" << std::endl
- << "function call: fragment(24, 0x08, 0x41)" << std::endl;
-
- compare_packets(l2cap_expected, l2cap_received);
-
- sdu.clear();
- l2cap_expected.reset();
- l2cap_received.reset();
-} // End Fragment Test3
-
-// Begin Fragment Test4
-TEST_F(L2capTest, fragmentPayloadTest) {
- std::vector<std::shared_ptr<L2capSdu> > sdu;
- std::shared_ptr<L2capPacket> l2cap_expected;
- std::shared_ptr<L2capPacket> l2cap_received;
-
- sdu.push_back(L2capSdu::L2capSduConstructor(empty_sdu_payload[0]));
- sdu.push_back(L2capSdu::L2capSduConstructor(empty_sdu_payload[1]));
-
- l2cap_expected = L2capPacket::assemble(sdu);
-
- sdu.clear();
-
- // Test4: Packet with no payload
- sdu = l2cap_expected->fragment(16, 0x02, 0x41);
-
- l2cap_received = L2capPacket::assemble(sdu);
- ASSERT_NE(l2cap_received, nullptr) << "packet reassembly failed after fragment" << std::endl
- << "Test4: Packet with no payload" << std::endl
- << "sdu used: empty_sdu_payload" << std::endl
- << "function call: fragment(16, 0x02, 0x41)" << std::endl;
-
- compare_packets(l2cap_expected, l2cap_received);
-
- sdu.clear();
- l2cap_expected.reset();
- l2cap_received.reset();
-} // End Fragment Test4
-
-// Begin Fragment Test5
-TEST_F(L2capTest, fragmentSegmentSizeTest) {
- std::vector<std::shared_ptr<L2capSdu> > sdu;
- std::shared_ptr<L2capPacket> l2cap_expected;
- std::shared_ptr<L2capPacket> l2cap_received;
-
- sdu.push_back(L2capSdu::L2capSduConstructor(good_sdu[0]));
- sdu.push_back(L2capSdu::L2capSduConstructor(good_sdu[1]));
- sdu.push_back(L2capSdu::L2capSduConstructor(good_sdu[2]));
-
- l2cap_expected = L2capPacket::assemble(sdu);
-
- sdu.clear();
-
- // Test5: Larger segment size than packet size
- sdu = l2cap_expected->fragment(256, 0x02, 0x41);
-
- l2cap_received = L2capPacket::assemble(sdu);
- ASSERT_NE(l2cap_received, nullptr) << "packet reassembly failed after fragment" << std::endl
- << "Test5: Segment size > Payload" << std::endl
- << "sdu used: good_sdu" << std::endl
- << "function call: fragment(256, 0x02, 0x41)" << std::endl;
-
- compare_packets(l2cap_expected, l2cap_received);
-
- sdu.clear();
- l2cap_expected.reset();
- l2cap_received.reset();
-} // End Fragment Test5
-
-// Begin Fragment Test6
-TEST_F(L2capTest, fragmentSegmentSizeTest2) {
- std::vector<std::shared_ptr<L2capSdu> > sdu;
- std::shared_ptr<L2capPacket> l2cap_expected;
- std::shared_ptr<L2capPacket> l2cap_received;
-
- sdu.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_1));
- sdu.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_2));
- sdu.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_3));
- sdu.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_4));
- sdu.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_5));
- sdu.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_6));
- sdu.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_7));
- sdu.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_8));
- sdu.push_back(L2capSdu::L2capSduConstructor(l2cap_test_packet_9));
-
- l2cap_expected = L2capPacket::assemble(sdu);
- sdu.clear();
-
- // Test6: Small segment size on large packet.
- sdu = l2cap_expected->fragment(512, 0x02, 0x41);
-
- l2cap_received = L2capPacket::assemble(sdu);
- ASSERT_NE(l2cap_received, nullptr) << "packet reassembly failed after fragment" << std::endl
- << "Test6: Small Segment request on large packet" << std::endl
- << "sdu used: l2cap_test_packet_[1-9]" << std::endl
- << "function call: fragment(64, 0x02, 0x41)" << std::endl;
-
- compare_packets(l2cap_expected, l2cap_received);
-
- sdu.clear();
- l2cap_expected.reset();
- l2cap_received.reset();
-} // End Fragment Test6
-
-} // namespace test_vendor_lib
diff --git a/system/vendor_libs/test_vendor_lib/test/link_layer_socket_device_test.cc b/system/vendor_libs/test_vendor_lib/test/link_layer_socket_device_test.cc
deleted file mode 100644
index 5b4ee49dc2..0000000000
--- a/system/vendor_libs/test_vendor_lib/test/link_layer_socket_device_test.cc
+++ /dev/null
@@ -1,296 +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.
- */
-
-#include "model/devices/link_layer_socket_device.h"
-
-#include <gtest/gtest.h>
-#include <cstdint>
-#include <cstring>
-#include <vector>
-
-#include <netdb.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "model/setup/async_manager.h"
-#include "packets/link_layer/command_view.h"
-
-std::vector<uint8_t> count = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-};
-
-using test_vendor_lib::packets::CommandBuilder;
-using test_vendor_lib::packets::CommandView;
-using test_vendor_lib::packets::LinkLayerPacketBuilder;
-using test_vendor_lib::packets::LinkLayerPacketView;
-using test_vendor_lib::packets::PacketView;
-using test_vendor_lib::packets::View;
-
-static const size_t kMaxConnections = 300;
-
-namespace test_vendor_lib {
-
-class LinkLayerSocketDeviceTest : public ::testing::Test {
- public:
- static const uint16_t kPort = 6123;
-
- protected:
- class MockPhyLayer : public PhyLayer {
- public:
- MockPhyLayer(const std::function<void(std::shared_ptr<LinkLayerPacketBuilder>)>& on_receive)
- : PhyLayer(Phy::Type::LOW_ENERGY, 0, [](LinkLayerPacketView) {}), on_receive_(on_receive) {}
- void Send(const std::shared_ptr<LinkLayerPacketBuilder> packet) override {
- on_receive_(packet);
- }
- void Receive(LinkLayerPacketView) override {}
- void TimerTick() override {}
-
- private:
- std::function<void(std::shared_ptr<LinkLayerPacketBuilder>)> on_receive_;
- };
-
- int StartServer() {
- struct sockaddr_in serv_addr;
- int fd = socket(AF_INET, SOCK_STREAM, 0);
- EXPECT_FALSE(fd < 0);
-
- memset(&serv_addr, 0, sizeof(serv_addr));
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_addr.s_addr = INADDR_ANY;
- serv_addr.sin_port = htons(kPort);
- int reuse_flag = 1;
- EXPECT_FALSE(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse_flag, sizeof(reuse_flag)) < 0);
- EXPECT_FALSE(bind(fd, (sockaddr*)&serv_addr, sizeof(serv_addr)) < 0);
-
- listen(fd, 1);
- return fd;
- }
-
- int AcceptConnection(int fd) {
- return accept(fd, NULL, NULL);
- }
-
- void ValidatePacket(size_t index, bool at_server, std::shared_ptr<LinkLayerPacketBuilder> received) {
- /* Convert the Builder into a View */
- std::shared_ptr<std::vector<uint8_t>> packet_ptr = std::make_shared<std::vector<uint8_t>>();
- std::back_insert_iterator<std::vector<uint8_t>> it(*packet_ptr);
- received->Serialize(it);
- LinkLayerPacketView received_view = LinkLayerPacketView::Create(packet_ptr);
-
- /* Validate received packet */
- ASSERT_EQ(received_view.GetSourceAddress(), source_);
- ASSERT_EQ(received_view.GetDestinationAddress(), dest_);
- ASSERT_EQ(Link::PacketType::COMMAND, received_view.GetType());
- CommandView command_view = CommandView::GetCommand(received_view);
- if (at_server) {
- ASSERT_EQ(client_opcodes_[index], command_view.GetOpcode());
- } else {
- ASSERT_EQ(server_opcodes_[index], command_view.GetOpcode());
- }
- auto args_itr = command_view.GetData();
- ASSERT_EQ(args_itr.NumBytesRemaining(), count.size());
- for (size_t i = 0; i < count.size(); i++) {
- ASSERT_EQ(*args_itr++, count[i]);
- }
- if (at_server) {
- validated_client_packets_[index]++;
- } else {
- validated_server_packets_[index]++;
- }
- }
-
- void SetUp() override {
- servers_.reserve(kMaxConnections);
- clients_.reserve(kMaxConnections);
- socket_fd_ = StartServer();
-
- async_manager_.WatchFdForNonBlockingReads(socket_fd_, [this](int fd) {
- int connection_fd = AcceptConnection(fd);
- ASSERT_GE(connection_fd, 0);
- size_t index = servers_.size();
- servers_.emplace_back(connection_fd, Phy::Type::LOW_ENERGY);
- ASSERT_EQ(servers_.size() - 1, index) << "Race condition";
- std::shared_ptr<MockPhyLayer> mock_phy = std::make_shared<MockPhyLayer>(
- [this, index](std::shared_ptr<LinkLayerPacketBuilder> received) { ValidatePacket(index, true, received); });
- servers_[index].RegisterPhyLayer(mock_phy);
- });
- }
-
- void TearDown() override {
- async_manager_.StopWatchingFileDescriptor(socket_fd_);
- close(socket_fd_);
- }
-
- int ConnectClient() {
- int socket_cli_fd = socket(AF_INET, SOCK_STREAM, 0);
- EXPECT_FALSE(socket_cli_fd < 0);
-
- struct hostent* server;
- server = gethostbyname("localhost");
- EXPECT_FALSE(server == NULL);
-
- struct sockaddr_in serv_addr;
- memset((void*)&serv_addr, 0, sizeof(serv_addr));
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_addr.s_addr = INADDR_ANY;
- serv_addr.sin_port = htons(kPort);
-
- int result = connect(socket_cli_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
- EXPECT_FALSE(result < 0);
-
- EXPECT_GE(socket_cli_fd, 0);
-
- return socket_cli_fd;
- }
-
- void ValidateConnection(size_t pair_id) {
- ASSERT_GT(clients_.size(), pair_id);
- ASSERT_GT(servers_.size(), pair_id);
- }
-
- size_t CreateConnection() {
- int fd = ConnectClient();
- size_t index = clients_.size();
- clients_.emplace_back(fd, Phy::Type::LOW_ENERGY);
- std::shared_ptr<MockPhyLayer> mock_phy = std::make_shared<MockPhyLayer>(
- [this, index](std::shared_ptr<LinkLayerPacketBuilder> received) { ValidatePacket(index, false, received); });
- clients_[index].RegisterPhyLayer(mock_phy);
- for (size_t timeout = 10; timeout > 0 && clients_.size() > servers_.size(); timeout--) {
- sleep(0); // Wait for server to be created
- }
- ValidateConnection(index);
- return index;
- }
-
- LinkLayerPacketView NextPacket() {
- std::shared_ptr<std::vector<uint8_t>> count_shared = std::make_shared<std::vector<uint8_t>>(count);
- LinkLayerPacketView view = LinkLayerPacketView::Create(count_shared);
- return view;
- }
-
- void SendFromClient(size_t pair_id) {
- ASSERT_GT(clients_.size(), pair_id);
- LinkLayerPacketView view = NextPacket();
- client_opcodes_[pair_id] = CommandView::GetCommand(view).GetOpcode();
- clients_[pair_id].IncomingPacket(view);
- }
-
- void SendFromServer(size_t pair_id) {
- ASSERT_GT(servers_.size(), pair_id);
- LinkLayerPacketView view = NextPacket();
- server_opcodes_[pair_id] = CommandView::GetCommand(view).GetOpcode();
- servers_[pair_id].IncomingPacket(view);
- }
-
- void ReadFromClient(size_t pair_id) {
- ASSERT_GT(clients_.size(), pair_id);
- size_t validated_packets = validated_server_packets_[pair_id];
- for (size_t tries = 0; tries < 10 && validated_server_packets_[pair_id] == validated_packets; tries++) {
- clients_[pair_id].TimerTick();
- }
- ASSERT_EQ(validated_server_packets_[pair_id], validated_packets + 1);
- }
-
- void ReadFromServer(size_t pair_id) {
- ASSERT_GT(servers_.size(), pair_id);
- size_t validated_packets = validated_client_packets_[pair_id];
- for (size_t tries = 0; tries < 10 && validated_client_packets_[pair_id] == validated_packets; tries++) {
- servers_[pair_id].TimerTick();
- }
- ASSERT_EQ(validated_client_packets_[pair_id], validated_packets + 1);
- }
-
- private:
- uint16_t packet_id_{1};
- AsyncManager async_manager_;
- int socket_fd_;
- std::vector<LinkLayerSocketDevice> servers_;
- std::vector<LinkLayerSocketDevice> clients_;
- uint16_t server_opcodes_[kMaxConnections]{0};
- uint16_t client_opcodes_[kMaxConnections]{0};
- size_t validated_server_packets_[kMaxConnections]{0};
- size_t validated_client_packets_[kMaxConnections]{0};
- Address source_{{1, 2, 3, 4, 5, 6}};
- Address dest_{{6, 5, 4, 3, 2, 1}};
-};
-
-TEST_F(LinkLayerSocketDeviceTest, TestClientFirst) {
- size_t pair_id = CreateConnection();
- ASSERT_EQ(pair_id, 0u);
- ValidateConnection(pair_id);
-
- SendFromClient(pair_id);
- ReadFromServer(pair_id);
-}
-
-TEST_F(LinkLayerSocketDeviceTest, TestServerFirst) {
- size_t pair_id = CreateConnection();
- ASSERT_EQ(pair_id, 0u);
-
- SendFromServer(pair_id);
- ReadFromClient(pair_id);
-}
-
-TEST_F(LinkLayerSocketDeviceTest, TestMultiplePackets) {
- static const int num_packets = 30;
- size_t pair_id = CreateConnection();
- ASSERT_EQ(pair_id, 0u);
- for (int i = 0; i < num_packets; i++) {
- SendFromClient(pair_id);
- SendFromServer(pair_id);
- ReadFromServer(pair_id);
- ReadFromClient(pair_id);
- }
-}
-
-TEST_F(LinkLayerSocketDeviceTest, TestMultipleConnectionsFromServer) {
- static size_t last_pair_id = -1;
- size_t pair_id;
- for (size_t i = 0; i < kMaxConnections; i++) {
- pair_id = CreateConnection();
- ASSERT_EQ(pair_id, last_pair_id + 1);
- last_pair_id = pair_id;
- SendFromServer(pair_id);
- ReadFromClient(pair_id);
- }
-}
-
-TEST_F(LinkLayerSocketDeviceTest, TestMultipleConnectionsFromClient) {
- for (size_t i = 0; i < kMaxConnections; i++) {
- size_t pair_id = CreateConnection();
- ASSERT_EQ(pair_id, i);
- SendFromClient(pair_id);
- ReadFromServer(pair_id);
- }
-}
-
-TEST_F(LinkLayerSocketDeviceTest, TestMultipleConnections) {
- for (size_t i = 0; i < kMaxConnections; i++) {
- size_t pair_id = CreateConnection();
- ASSERT_EQ(pair_id, i);
- SendFromClient(pair_id);
- SendFromServer(pair_id);
- ReadFromClient(pair_id);
- ReadFromServer(pair_id);
- }
-}
-
-} // namespace test_vendor_lib
diff --git a/system/vendor_libs/test_vendor_lib/test/packet_stream_unittest.cc b/system/vendor_libs/test_vendor_lib/test/packet_stream_unittest.cc
deleted file mode 100644
index ab2d767da9..0000000000
--- a/system/vendor_libs/test_vendor_lib/test/packet_stream_unittest.cc
+++ /dev/null
@@ -1,116 +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.
-//
-
-#include "packet_stream.h"
-#include "command_packet.h"
-#include "event_packet.h"
-#include "packet.h"
-
-#include <gtest/gtest.h>
-#include <cstdint>
-#include <memory>
-#include <vector>
-using std::vector;
-
-#include "hci/include/hci_hal.h"
-
-#include <sys/socket.h>
-
-namespace {
-const char small_payload[] = "foo bar baz";
-const char large_payload[] =
- "Aristotle's principles will then be no more principles to him, than those "
- "of Epicurus and the Stoics: let this diversity of opinions be propounded "
- "to, and laid before him; he will himself choose, if he be able; if not, "
- "he will remain in doubt.";
-} // namespace
-
-namespace test_vendor_lib {
-
-class PacketStreamTest : public ::testing::Test {
- public:
- PacketStreamTest() {
- socketpair(AF_LOCAL, SOCK_STREAM, 0, socketpair_fds_);
- CheckSocketpairInit();
- }
-
- ~PacketStreamTest() override {
- close(socketpair_fds_[0]);
- close(socketpair_fds_[1]);
- }
-
- void CheckedReceiveCommand(const char* payload, uint16_t opcode) {
- uint8_t payload_size = strlen(payload);
- vector<uint8_t> packet;
-
- packet.push_back(DATA_TYPE_COMMAND);
- packet.push_back(opcode);
- packet.push_back(opcode >> 8);
- packet.push_back(payload_size);
-
- // Set the packet's payload.
- for (int i = 0; i < payload_size; ++i) packet.push_back(payload[i]);
-
- // Send the packet to |packet_stream_|.
- write(socketpair_fds_[1], &packet[1], packet.size());
-
- // Read the command packet.
- std::unique_ptr<CommandPacket> command = packet_stream_.ReceiveCommand(socketpair_fds_[0]);
-
- const vector<uint8_t> received_payload = command->GetPayload();
-
- // Validate the packet by checking that it's the appropriate size and then
- // checking each byte.
- EXPECT_EQ(packet.size(), command->GetPacketSize());
- EXPECT_EQ(DATA_TYPE_COMMAND, command->GetType());
- EXPECT_EQ(opcode, command->GetOpcode());
- EXPECT_EQ(static_cast<size_t>(payload_size + 1), command->GetPayloadSize());
- EXPECT_EQ(payload_size, received_payload[0]);
- for (int i = 0; i < payload_size; ++i) EXPECT_EQ(packet[4 + i], received_payload[i + 1]);
- }
-
- protected:
- PacketStream packet_stream_;
-
- int socketpair_fds_[2];
-
- private:
- // Workaround because ASSERT cannot be used directly in a constructor
- void CheckSocketpairInit() {
- ASSERT_TRUE(socketpair_fds_[0] > 0);
- ASSERT_TRUE(socketpair_fds_[1] > 0);
- }
-};
-
-TEST_F(PacketStreamTest, ReceivePacketType) {
- serial_data_type_t command_type = DATA_TYPE_COMMAND;
- write(socketpair_fds_[1], &command_type, 1);
- EXPECT_EQ(command_type, packet_stream_.ReceivePacketType(socketpair_fds_[0]));
-}
-
-TEST_F(PacketStreamTest, ReceiveEmptyCommand) {
- CheckedReceiveCommand("", HCI_RESET);
-}
-
-TEST_F(PacketStreamTest, ReceiveSmallCommand) {
- CheckedReceiveCommand(small_payload, HCI_RESET);
-}
-
-TEST_F(PacketStreamTest, ReceiveLargeCommand) {
- CheckedReceiveCommand(large_payload, HCI_RESET);
-}
-
-} // namespace test_vendor_lib
diff --git a/system/vendor_libs/test_vendor_lib/types/Android.bp b/system/vendor_libs/test_vendor_lib/types/Android.bp
deleted file mode 100644
index e68af2acf5..0000000000
--- a/system/vendor_libs/test_vendor_lib/types/Android.bp
+++ /dev/null
@@ -1,45 +0,0 @@
-// Bluetooth types
-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_headers {
- name: "libbt-rootcanal-types-header",
- export_include_dirs: ["./"],
- vendor_available: true,
- host_supported: true,
-}
-
-cc_library_static {
- name: "libbt-rootcanal-types",
- vendor_available: true,
- defaults: ["fluoride_types_defaults"],
- cflags: [
- /* we export all classes, so change default visibility, instead of having EXPORT_SYMBOL on each class*/
- "-fvisibility=default",
- ],
- host_supported: true,
- srcs: [
- "bluetooth/uuid.cc",
- ],
- header_libs: ["libbt-rootcanal-types-header"],
- export_header_lib_headers: ["libbt-rootcanal-types-header"],
-}
-
-cc_test {
- name: "rootcanal-test_types",
- test_suites: ["device-tests"],
- defaults: ["fluoride_defaults"],
- host_supported: true,
- srcs: [
- "test/bluetooth/uuid_unittest.cc",
- ],
- static_libs: [
- "libbt-rootcanal-types",
- ],
-}
diff --git a/system/vendor_libs/test_vendor_lib/types/BUILD.gn b/system/vendor_libs/test_vendor_lib/types/BUILD.gn
deleted file mode 100644
index 8629d3be76..0000000000
--- a/system/vendor_libs/test_vendor_lib/types/BUILD.gn
+++ /dev/null
@@ -1,65 +0,0 @@
-#
-# Copyright 2017 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("types") {
- cflags = [
- "-fvisibility=default",
- ]
-
- sources = [
- "bluetooth/uuid.cc",
- "le_address.cc",
- "address.cc",
- ]
-
- include_dirs = [
- "//bt/system",
- ]
-
- configs += [
- "//bt/system:target_defaults",
- ]
-}
-
-if (use.test) {
- executable("types_unittests") {
- sources = [
- "test/address_unittest.cc",
- "test/bluetooth/uuid_unittest.cc",
- ]
-
- include_dirs = [
- "//bt/system",
- ]
-
- libs = [
- "dl",
- "pthread",
- "resolv",
- "rt",
- "z",
- ]
-
- deps = [
- "//bt/system/types",
- ]
-
- configs += [
- "//bt/system:external_gmock_main",
- "//bt/system:target_defaults",
- ]
- }
-}
diff --git a/system/vendor_libs/test_vendor_lib/types/bluetooth/uuid.cc b/system/vendor_libs/test_vendor_lib/types/bluetooth/uuid.cc
deleted file mode 100644
index cc1420642e..0000000000
--- a/system/vendor_libs/test_vendor_lib/types/bluetooth/uuid.cc
+++ /dev/null
@@ -1,182 +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.
- *
- ******************************************************************************/
-
-#include "uuid.h"
-
-#include <algorithm>
-#include <cstring>
-#include <random>
-
-namespace bluetooth {
-
-static_assert(sizeof(Uuid) == 16, "Uuid must be 16 bytes long!");
-
-using UUID128Bit = Uuid::UUID128Bit;
-
-const Uuid Uuid::kEmpty = Uuid::From128BitBE(UUID128Bit{{0x00}});
-
-namespace {
-constexpr Uuid kBase = Uuid::From128BitBE(
- UUID128Bit{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb}});
-} // namespace
-
-size_t Uuid::GetShortestRepresentationSize() const {
- if (memcmp(uu.data() + kNumBytes32, kBase.uu.data() + kNumBytes32, kNumBytes128 - kNumBytes32) != 0) {
- return kNumBytes128;
- }
-
- if (uu[0] == 0 && uu[1] == 0) return kNumBytes16;
-
- return kNumBytes32;
-}
-
-bool Uuid::Is16Bit() const {
- return GetShortestRepresentationSize() == kNumBytes16;
-}
-
-uint16_t Uuid::As16Bit() const {
- return (((uint16_t)uu[2]) << 8) + uu[3];
-}
-
-uint32_t Uuid::As32Bit() const {
- return (((uint32_t)uu[0]) << 24) + (((uint32_t)uu[1]) << 16) + (((uint32_t)uu[2]) << 8) + uu[3];
-}
-
-Uuid Uuid::FromString(const std::string& uuid, bool* is_valid) {
- if (is_valid) *is_valid = false;
- Uuid ret = kBase;
-
- if (uuid.empty()) return ret;
-
- uint8_t* p = ret.uu.data();
- if (uuid.size() == kString128BitLen) {
- if (uuid[8] != '-' || uuid[13] != '-' || uuid[18] != '-' || uuid[23] != '-') {
- return ret;
- }
-
- int c;
- int rc = sscanf(uuid.c_str(),
- "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx"
- "-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%n",
- &p[0], &p[1], &p[2], &p[3], &p[4], &p[5], &p[6], &p[7], &p[8], &p[9], &p[10], &p[11], &p[12],
- &p[13], &p[14], &p[15], &c);
- if (rc != 16) return ret;
- if (c != kString128BitLen) return ret;
-
- if (is_valid) *is_valid = true;
- } else if (uuid.size() == 8) {
- int c;
- int rc = sscanf(uuid.c_str(), "%02hhx%02hhx%02hhx%02hhx%n", &p[0], &p[1], &p[2], &p[3], &c);
- if (rc != 4) return ret;
- if (c != 8) return ret;
-
- if (is_valid) *is_valid = true;
- } else if (uuid.size() == 4) {
- int c;
- int rc = sscanf(uuid.c_str(), "%02hhx%02hhx%n", &p[2], &p[3], &c);
- if (rc != 2) return ret;
- if (c != 4) return ret;
-
- if (is_valid) *is_valid = true;
- }
-
- return ret;
-}
-
-Uuid Uuid::From16Bit(uint16_t uuid16) {
- Uuid u = kBase;
-
- u.uu[2] = (uint8_t)((0xFF00 & uuid16) >> 8);
- u.uu[3] = (uint8_t)(0x00FF & uuid16);
- return u;
-}
-
-Uuid Uuid::From32Bit(uint32_t uuid32) {
- Uuid u = kBase;
-
- u.uu[0] = (uint8_t)((0xFF000000 & uuid32) >> 24);
- u.uu[1] = (uint8_t)((0x00FF0000 & uuid32) >> 16);
- u.uu[2] = (uint8_t)((0x0000FF00 & uuid32) >> 8);
- u.uu[3] = (uint8_t)(0x000000FF & uuid32);
- return u;
-}
-
-Uuid Uuid::From128BitBE(const uint8_t* uuid) {
- UUID128Bit tmp;
- memcpy(tmp.data(), uuid, kNumBytes128);
- return From128BitBE(tmp);
-}
-
-Uuid Uuid::From128BitLE(const UUID128Bit& uuid) {
- Uuid u;
- std::reverse_copy(uuid.data(), uuid.data() + kNumBytes128, u.uu.begin());
- return u;
-}
-
-Uuid Uuid::From128BitLE(const uint8_t* uuid) {
- UUID128Bit tmp;
- memcpy(tmp.data(), uuid, kNumBytes128);
- return From128BitLE(tmp);
-}
-
-const UUID128Bit Uuid::To128BitLE() const {
- UUID128Bit le;
- std::reverse_copy(uu.data(), uu.data() + kNumBytes128, le.begin());
- return le;
-}
-
-const UUID128Bit& Uuid::To128BitBE() const {
- return uu;
-}
-
-Uuid Uuid::GetRandom() {
- Uuid uuid;
- std::independent_bits_engine<std::default_random_engine, 8, unsigned int>
- engine;
- std::generate(std::begin(uuid.uu), std::end(uuid.uu), std::ref(engine));
- return uuid;
-}
-
-bool Uuid::IsEmpty() const {
- return *this == kEmpty;
-}
-
-bool Uuid::operator<(const Uuid& rhs) const {
- return std::lexicographical_compare(uu.begin(), uu.end(), rhs.uu.begin(), rhs.uu.end());
-}
-
-bool Uuid::operator==(const Uuid& rhs) const {
- return uu == rhs.uu;
-}
-
-bool Uuid::operator!=(const Uuid& rhs) const {
- return uu != rhs.uu;
-}
-
-std::string Uuid::ToString() const {
- char buffer[37];
-
- snprintf(
- buffer, sizeof(buffer),
- "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
- uu[0], uu[1], uu[2], uu[3], uu[4], uu[5], uu[6], uu[7], uu[8], uu[9],
- uu[10], uu[11], uu[12], uu[13], uu[14], uu[15]);
-
- return buffer;
-}
-} // namespace bluetooth
diff --git a/system/vendor_libs/test_vendor_lib/types/bluetooth/uuid.h b/system/vendor_libs/test_vendor_lib/types/bluetooth/uuid.h
deleted file mode 100644
index cea2cf48d8..0000000000
--- a/system/vendor_libs/test_vendor_lib/types/bluetooth/uuid.h
+++ /dev/null
@@ -1,140 +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.
- *
- ******************************************************************************/
-
-#pragma once
-
-#include <stdint.h>
-#include <array>
-#include <ostream>
-#include <string>
-
-namespace bluetooth {
-
-// This class is representing Bluetooth UUIDs across whole stack.
-// Here are some general endianness rules:
-// 1. UUID is internally kept as as Big Endian.
-// 2. Bytes representing UUID coming from upper layers, Java or Binder, are Big
-// Endian.
-// 3. Bytes representing UUID coming from lower layer, HCI packets, are Little
-// Endian.
-// 4. UUID in storage is always string.
-class Uuid final {
- public:
- static constexpr size_t kNumBytes128 = 16;
- static constexpr size_t kNumBytes32 = 4;
- static constexpr size_t kNumBytes16 = 2;
-
- static constexpr size_t kString128BitLen = 36;
-
- static const Uuid kEmpty; // 00000000-0000-0000-0000-000000000000
-
- using UUID128Bit = std::array<uint8_t, kNumBytes128>;
-
- Uuid() = default;
-
- // Creates and returns a random 128-bit UUID.
- static Uuid GetRandom();
-
- // Returns the shortest possible representation of this UUID in bytes. Either
- // kNumBytes16, kNumBytes32, or kNumBytes128
- size_t GetShortestRepresentationSize() const;
-
- // Returns true if this UUID can be represented as 16 bit.
- bool Is16Bit() const;
-
- // Returns 16 bit Little Endian representation of this UUID. Use
- // GetShortestRepresentationSize() or Is16Bit() before using this method.
- uint16_t As16Bit() const;
-
- // Returns 32 bit Little Endian representation of this UUID. Use
- // GetShortestRepresentationSize() before using this method.
- uint32_t As32Bit() const;
-
- // Converts string representing 128, 32, or 16 bit UUID in
- // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, xxxxxxxx, or xxxx format to UUID. If
- // set, optional is_valid parameter will be set to true if conversion is
- // successfull, false otherwise.
- static Uuid FromString(const std::string& uuid, bool* is_valid = nullptr);
-
- // Converts 16bit Little Endian representation of UUID to UUID
- static Uuid From16Bit(uint16_t uuid16bit);
-
- // Converts 32bit Little Endian representation of UUID to UUID
- static Uuid From32Bit(uint32_t uuid32bit);
-
- // Converts 128 bit Big Endian array representing UUID to UUID.
- static constexpr Uuid From128BitBE(const UUID128Bit& uuid) {
- Uuid u(uuid);
- return u;
- }
-
- // Converts 128 bit Big Endian array representing UUID to UUID. |uuid| points
- // to beginning of array.
- static Uuid From128BitBE(const uint8_t* uuid);
-
- // Converts 128 bit Little Endian array representing UUID to UUID.
- static Uuid From128BitLE(const UUID128Bit& uuid);
-
- // Converts 128 bit Little Endian array representing UUID to UUID. |uuid|
- // points to beginning of array.
- static Uuid From128BitLE(const uint8_t* uuid);
-
- // Returns 128 bit Little Endian representation of this UUID
- const UUID128Bit To128BitLE() const;
-
- // Returns 128 bit Big Endian representation of this UUID
- const UUID128Bit& To128BitBE() const;
-
- // Returns string representing this UUID in
- // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format, lowercase.
- std::string ToString() const;
-
- // Returns true if this UUID is equal to kEmpty
- bool IsEmpty() const;
-
- bool operator<(const Uuid& rhs) const;
- bool operator==(const Uuid& rhs) const;
- bool operator!=(const Uuid& rhs) const;
-
- private:
- constexpr Uuid(const UUID128Bit& val) : uu{val} {};
-
- // Network-byte-ordered ID (Big Endian).
- UUID128Bit uu;
-};
-} // namespace bluetooth
-
-inline std::ostream& operator<<(std::ostream& os, const bluetooth::Uuid& a) {
- os << a.ToString();
- return os;
-}
-
-// Custom std::hash specialization so that bluetooth::UUID can be used as a key
-// in std::unordered_map.
-namespace std {
-
-template <>
-struct hash<bluetooth::Uuid> {
- std::size_t operator()(const bluetooth::Uuid& key) const {
- const auto& uuid_bytes = key.To128BitBE();
- std::hash<std::string> hash_fn;
- return hash_fn(std::string(reinterpret_cast<const char*>(uuid_bytes.data()), uuid_bytes.size()));
- }
-};
-
-} // namespace std
diff --git a/system/vendor_libs/test_vendor_lib/types/test/bluetooth/uuid_unittest.cc b/system/vendor_libs/test_vendor_lib/types/test/bluetooth/uuid_unittest.cc
deleted file mode 100644
index be2ef102f1..0000000000
--- a/system/vendor_libs/test_vendor_lib/types/test/bluetooth/uuid_unittest.cc
+++ /dev/null
@@ -1,155 +0,0 @@
-/******************************************************************************
- *
- * Copyright (C) 2017 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.
- *
- ******************************************************************************/
-
-#include <bluetooth/uuid.h>
-#include <gtest/gtest.h>
-
-using bluetooth::Uuid;
-
-static const Uuid ONES = Uuid::From128BitBE(
- Uuid::UUID128Bit{{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}});
-
-static const Uuid SEQUENTIAL = Uuid::From128BitBE(
- Uuid::UUID128Bit{{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89}});
-
-constexpr Uuid kBase = Uuid::From128BitBE(
- Uuid::UUID128Bit{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb}});
-
-TEST(UuidTest, IsEmpty) {
- EXPECT_TRUE(Uuid::kEmpty.IsEmpty());
- EXPECT_FALSE(kBase.IsEmpty());
-}
-
-TEST(UuidTest, GetShortestRepresentationSize) {
- EXPECT_TRUE(Uuid::kNumBytes16 == kBase.GetShortestRepresentationSize());
- EXPECT_TRUE(Uuid::kNumBytes32 == Uuid::From32Bit(0x01234567).GetShortestRepresentationSize());
- EXPECT_TRUE(Uuid::kNumBytes128 == Uuid::kEmpty.GetShortestRepresentationSize());
-}
-
-TEST(UuidTest, As16Bit) {
- // Even though this is is not 16bit UUID, we should be able to get proper bits
- EXPECT_EQ((uint16_t)0x1111, ONES.As16Bit());
- EXPECT_EQ((uint16_t)0x4567, SEQUENTIAL.As16Bit());
- EXPECT_EQ((uint16_t)0x0000, kBase.As16Bit());
-}
-
-TEST(UuidTest, As32Bit) {
- // Even though this is is not 32bit UUID, we should be able to get proper bits
- EXPECT_EQ((uint32_t)0x11111111, ONES.As32Bit());
- EXPECT_EQ((uint32_t)0x01234567, SEQUENTIAL.As32Bit());
- EXPECT_EQ((uint32_t)0x00000000, kBase.As32Bit());
- EXPECT_EQ((uint32_t)0x12345678, Uuid::From32Bit(0x12345678).As32Bit());
-}
-
-TEST(UuidTest, Is16Bit) {
- EXPECT_FALSE(ONES.Is16Bit());
- EXPECT_FALSE(SEQUENTIAL.Is16Bit());
- EXPECT_TRUE(kBase.Is16Bit());
- EXPECT_TRUE(Uuid::FromString("1ae8").Is16Bit());
-}
-
-TEST(UuidTest, From16Bit) {
- EXPECT_EQ(Uuid::From16Bit(0x0000), kBase);
-
- const uint8_t u2[] = {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
- Uuid uuid = Uuid::From16Bit(0x0001);
- EXPECT_TRUE(memcmp(&uuid, u2, sizeof(u2)) == 0);
-
- const uint8_t u3[] = {0x00, 0x00, 0x55, 0x3e, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
- uuid = Uuid::From16Bit(0x553e);
- EXPECT_TRUE(memcmp(&uuid, u3, sizeof(u3)) == 0);
-
- const uint8_t u4[] = {0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
- uuid = Uuid::From16Bit(0xffff);
- EXPECT_TRUE(memcmp(&uuid, u4, sizeof(u4)) == 0);
-}
-
-TEST(UuidTest, From32Bit) {
- EXPECT_EQ(Uuid::From32Bit(0x00000000), kBase);
-
- const uint8_t u2[] = {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
- Uuid uuid = Uuid::From32Bit(0x00000001);
- EXPECT_TRUE(memcmp(&uuid, u2, sizeof(u2)) == 0);
-
- const uint8_t u3[] = {0x33, 0x44, 0x55, 0x3e, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
- uuid = Uuid::From32Bit(0x3344553e);
- EXPECT_TRUE(memcmp(&uuid, u3, sizeof(u3)) == 0);
-
- const uint8_t u4[] = {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
- uuid = Uuid::From32Bit(0xffffffff);
- EXPECT_TRUE(memcmp(&uuid, u4, sizeof(u4)) == 0);
-}
-
-TEST(UuidTest, ToString) {
- const std::string UUID_BASE_STR = "00000000-0000-1000-8000-00805f9b34fb";
- const std::string UUID_EMP_STR = "00000000-0000-0000-0000-000000000000";
- const std::string UUID_ONES_STR = "11111111-1111-1111-1111-111111111111";
- const std::string UUID_SEQ_STR = "01234567-89ab-cdef-abcd-ef0123456789";
-
- EXPECT_EQ(UUID_BASE_STR, kBase.ToString());
- EXPECT_EQ(UUID_EMP_STR, Uuid::kEmpty.ToString());
- EXPECT_EQ(UUID_ONES_STR, ONES.ToString());
- EXPECT_EQ(UUID_SEQ_STR, SEQUENTIAL.ToString());
-
- Uuid uuid = Uuid::From32Bit(0x12345678);
- EXPECT_EQ("12345678-0000-1000-8000-00805f9b34fb", uuid.ToString());
-}
-
-TEST(BtifStorageTest, test_string_to_uuid) {
- const uint8_t u1[] = {0xe3, 0x9c, 0x62, 0x85, 0x86, 0x7f, 0x4b, 0x1d, 0x9d, 0xb0, 0x35, 0xfb, 0xd9, 0xae, 0xbf, 0x22};
- bool is_valid = false;
- Uuid uuid = Uuid::FromString("e39c6285-867f-4b1d-9db0-35fbd9aebf22", &is_valid);
- EXPECT_TRUE(is_valid);
- EXPECT_TRUE(memcmp(&uuid, u1, sizeof(u1)) == 0);
-
- const uint8_t u2[] = {0x00, 0x00, 0x1a, 0xe8, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
- is_valid = false;
- uuid = Uuid::FromString("1Ae8", &is_valid);
- EXPECT_TRUE(is_valid);
- EXPECT_TRUE(memcmp(&uuid, u2, sizeof(u2)) == 0);
-
- const uint8_t u3[] = {0x12, 0x34, 0x11, 0x28, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
- is_valid = false;
- uuid = Uuid::FromString("12341128", &is_valid);
- EXPECT_TRUE(is_valid);
- EXPECT_TRUE(memcmp(&uuid, u3, sizeof(u3)) == 0);
-}
-
-TEST(BtifStorageTest, test_string_to_uuid_invalid) {
- bool is_valid = false;
- Uuid uuid = Uuid::FromString("This is not a UUID", &is_valid);
- EXPECT_FALSE(is_valid);
-
- uuid = Uuid::FromString("11212", &is_valid);
- EXPECT_FALSE(is_valid);
-
- uuid = Uuid::FromString("1121 ", &is_valid);
- EXPECT_FALSE(is_valid);
-
- uuid = Uuid::FromString("AGFE", &is_valid);
- EXPECT_FALSE(is_valid);
-
- uuid = Uuid::FromString("ABFG", &is_valid);
- EXPECT_FALSE(is_valid);
-
- uuid = Uuid::FromString("e39c6285867f14b1d9db035fbd9aebf22", &is_valid);
- EXPECT_FALSE(is_valid);
-
- uuid = Uuid::FromString("12234567-89ab-cdef-abcd-ef01234567ZZ", &is_valid);
- EXPECT_FALSE(is_valid);
-}